PHP currently has two separate approaches to handling errors:
- Errors
- Exceptions

Both have their issues.

Using and responding to errors requires that the returned value (if
there is one) perform double duty as both a potential valid response
AND, in the case of error, a flag that something went wrong. It's easy
to forget to check that a particular call succeeded and specifically
handle the error. I find myself constantly revisiting the
documentation to ensure I know the specific error flag for functions,
and performing post-hoc analysis of error logs to make sure I didn't
miss an error flag that I would be better served by handling in the
standard flow of my app.

Using and responding to exceptions is a heavy-handed approach, as any
particular exception can bring the entire application down.
Additionally, the process of raising and catching exceptions loses
context of the error, often requiring many different subclasses of
exceptions to maintain the error state. Issues arise when the language
constructs for exceptions are liberally used in situations that are
not truly "exceptional," and where the the exception handling becomes
a glorified goto.

I've been programming in Go, and the ability to pass back multiple
arguments, one of which is conventionally the error state, is
wonderful. It's simple, clear, concise, and powerful. The code calling
into the error-capable function knows the context and can handle
errors appropriately according to the application requirements.

In PHP, we could provide the ability to automatically pack up a
comma-separated list of values as an array:

return $var1, $var2;
// returns [$var1, $var2];

And, we could provide the ability to automatically unpack an array
into separate variables:

$var1, $var2 = myFunction();
// same as list($var1, $var2) = myFunction();

This functionality would allow us to embrace the convention that an
error is passed back as one of the return values:

$dbh, $err = db\connect();
// check for error
if ($err) {
    // handle db connection error
}
// carry on normally
$dbh->query("blah blah blah");

The simplicity (just passing back values), clarity (the code to handle
errors is proximal to the code that caused the error), and efficiency
(not having to create bunches of exception subclasses to maintain
context/information, and exceptions are expensive) of this approach is
a beautiful thing. You can see an explanation of Go error handling
here:
http://blog.golang.org/2011/07/error-handling-and-go.html

Concern 1: Isn't this just saving a few keystrokes?

Allowing developers to pass back an array and then access the members
of the array isn't the same thing, and we're not just saving a few
keystrokes if this is implemented. Providing this ability promotes
usage and clarity, and I'm confident Go would not have gotten
developers to follow this convention if the syntax didn't facilitate
the approach. I now write my Python code to handle errors in this same
manner, taking advantage of its ability to handle comma-separated
lists as tuples (something I didn't know about until recently, I must
confess):
http://stackoverflow.com/questions/423710/return-more-than-one-value-from-a-function-in-python

Concern 2: Why don't you just use Python or Go?

I really like using PHP for web development.

Concern 3: Are you saying we should get rid of errors and exceptions?

To be clear, errors have their place (maybe an extension failed to
load, or a warning about usage of undeclared vars, etc.), and so do
exceptions (for events that are truly "exceptional", that should cause
a major revision to the branching/flow of the application and/or stop
the application in its tracks if left unhandled.)

Adam

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to