At 5/30/2007 08:25 AM, Richard Davey wrote:
> In order that displayData() doesn't fall on its face, I would write
> the parent function in one of these ways:
> if (lookUpData()) displayData();
That's where our approach differs. If lookUpData falls flat on its
face, my error handler will take over completely, finally resulting in
an 'abortive' event, and never pass back to the parent. If an error is
of a critical enough nature the system needs to stop. If it's not
critical then the error handling within displayData() would detect it
has nothing to display and error in its own accord.
Hi Richard,
If you write your applications like this then they'll fall over when
something goes wrong -- and here I mean 'fall over' to mean aborting
suddenly with a technical error message. That can be useful to us
during development & debugging but isn't really useful or friendly to
the website visitor.
It also gives every subroutine that handles errors the responsibility
of deciding how to deal with the error -- whether to display it or
not, how to display it, etc. It makes code less portable from one
application to the next.
Consider another model in which subroutines report errors back to the
calling code but don't themselves 'act' on the errors. An error on a
low level can bubble back up to some higher parent level in the
application that knows what to do: whether to display and if so how
and in what human language, whether to email the developer, whether
to close down the application or continue, etc. An English SQL error
message is of little use to a web page in Japanese. It's usually a
mistake to display an SQL query in a public application because it
exposes sensitive details of the database architecture.
For example, we might want to generate the web page even if some part
of its content is unavailable due to the SQL error. This leaves the
visitor with a functional page from which they can navigate normally
even if part of the content is missing. On this high level, the
application might choose to behave nonchalantly as though SQL had
returned an empty recordset and report the hard error to the
webmaster behind the scenes.
This kind of error-handling architecture can be handled in a variety
of ways. One is to maintain a global error structure or class with a
variety of fields that relate to the last error: true/false, error
type, context, query code if applicable, etc. Because a low-level
error may in turn trigger higher-level errors as it bubbles back up,
it may make sense to turn this into an error stack to which each
calling function adds its understanding of the problem as the error
bubbles back up:
0: SQL error ZZZ in "SELECT * FROM `users` ..."
1: Can't query user list YYY
2: No users to display
When a high-level function receives an error state from a called
function, it can (if desired) walk down the stack to learn the
technical origin of the error as well as its implications during the bubble-up.
> In my programming style, I can't imagine wanting to write this code
> in such a way that lookUpData() didn't return some form of success or
> error indicator.
That's a *very* specific example though. My question was do people
place a 'return' statement at the end of **ALL** of their functions,
regardless of what that function actually did. In the code you gave
there is a fair argument both ways, but that isn't always the case.
Absolutely. I agree with most of the respondents to this thread:
return a value only if the caller needs to receive a value
back. Some languages (such as BASIC) distinguish between functions
that return values and subroutines that don't. Because PHP gives
only one type of function to call, with an option whether or not to
return anything, it's clearly up to us to design and impose that
architecture based on our knowledge and preferences.
Regards,
Paul
__________________________
Paul Novitski
Juniper Webcraft Ltd.
http://juniperwebcraft.com
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php