views:

247

answers:

4

I believe that in properly coded systems - errors (as errors or exceptions) should not be possible (with the exception of a DB/memcached server going down causing a query to fail). Our code should not rely on any assumptions to properly work and should be as bullet proof as possible.

However, in order to insure that our systems handle problems in the most user friendly way, we have to build and implement some kind of "catching system" to insure that, should anything ever go wrong, both our server staff and the end user will be taken care of.

To this end PHP offers two solutions - errors and exceptions. Errors consist of 5 values while Exceptions consist of 5 values wrapped in an object. Both allow backtracks which are invaluable while the app is being built.

The 5 values are $error_code, $error_message, $file, $line, $context

Normally, in our strive for proper OOP programming the default choice is always to pursue objects - but in a case like this I'm not sure as to how beneficial they really are. By using exceptions, addition memory is wasted do to the need of wrapping the values in an object (this also often requires extra files which contain the exception classes). Further more, you must wrap any code that you assume might fail in a TRY / CATCH {} block. This leaves the error handling method open to human error as points of failure may not be covered by the developer. In order to safe guard against this you can use the set_exception_handler which will be passed any exceptions not caught. The bad thing about the exception handler is that Execution will stop after the exception_handler is called - so there is no such thing as a recoverable/ignored exception should it not be caught in a try / catch block.

On the other hand, errors are always global and can be handled by any function/class set by the set_error_handler. This removes the need for extra exception classes, object memory, or lines of try / catch code. Like exceptions, errors also come with build in error codes which (unlike exceptions) you can use to continue script execution for minor or unimportant script problems. In addition, most of the PHP functions triggers errors so you will not be going against the flow of the language.

So given that you must support error handling anyway (do to the PHP language), what is the purpose of wasting extra code and memory also implementing exceptions? Are we just blindly doing this because it is an error in object form or is there a real benefit in application design that normal errors don't afford us?

+8  A: 

I stopped reading after this line:

I believe that in properly coded systems - errors (as errors or exceptions) should not be possible (with the exception of a DB/memcached server going down causing a query to fail).

That is the entire purpose of exceptions -- as a construct to manage exceptional circumstances in code.

If you are throwing exceptions as a part of unexceptional ordinary program flow, you're doing something wrong.

If you don't know why exceptions are useful for exceptional circumstances, then perhaps you need to spend some time with a true OO language. (Hint: PHP isn't a true OO language.)

Daniel Pryden
This is a very valid point. What I am mainly addressing is the use of exceptions in PHP frameworks to handle even the most common of errors. Exceptional Circumstances, i.e. requests to anything outside of the RAM and CPU (DB/another server/etc) might benefit from this.
Xeoncross
In a framework, throwing exceptions is an excellent idea. Any time a function is unable to perform the action it was asked to do, that is an exceptional situation. It is perfectly appropriate for the function to respond by throwing an exception, communicating this exceptional situation back to the caller. Essentially, by throwing an exception, you are giving callers the choice of either handling the situation *locally* (with a try/catch block) or at some higher level (possibly globally). Any other error mechanism doesn't offer that choice.
Daniel Pryden
+4  A: 

Along with the object oriented approach of all those errors come the great advantages of extending exceptions.

So you are able to catch all sub-exceptions of, lets say, IOExceptions in one catch block (FileNotFoundException, FileNotWritableException, ...), and all other exceptions in another one, where you might throw that exception again:

try
{
    // [...] (some code causing the exception)
}
catch(IOException $e)
{
    // do your processing here, like let's say set correct filemodes.
}
catch(Exception $e)
{
    // catches all other exceptions
}

Also they offer you a more standardized way of how you handle errors in your scripts. When you use try/catch blocks, the error handling will almost always look similar and in many cases is more self-explanatory than using normal errors with codes etc.

Which one can you understand better: ?

switch($errorCode)
{
    case 1450:
        // Create the database column
        break;
}

// or

catch(ColumnNotFoundException $e)
{
    // Create the database column
}
Sebastian Hoitz
So you are saying the advantage they offer in this case is more granular control over handling the error. Since PHP only has about 9 or so error types - by using exceptions you can add new types such as IO errors, happy errors, etc...
Xeoncross
Yes. Plus they offer a more standardized way of handling errors.
Sebastian Hoitz
How so? Please explain that statement.
Xeoncross
I edited my answer to contain that advantage of exceptions too.
Sebastian Hoitz
Thank you - though I can't stand switch blocks ;)
Xeoncross
A: 

The function fopen() has the possibility of returning the following:

If the open fails, an error of level E_WARNING is generated. You may use @ to suppress this warning.

You may choose to use the suppression operator, but it's generating a fair amount of overhead itself. try/catch blocks enable you to both capture this error, continue with regular execution, display custom errors to your users, and log the error all in one fell swoop. For me it's a no brainer as to the benefits of utilizing exception handling in my documents.

Also, if you use any piece of Zend Framework (including any of the Google API classes), you are expected to be handling exceptions on your own as they do and will occur.

cballou
Do the try/catch blocks in PHP also catch errors thrown by PHP functions? I didn't know that :)
Sebastian Hoitz
The problem with this statement is that you can do all of the above with errors so there is no benefit to be had by switching to exceptions. However, I agree that no code in the world should ever use the @ symbol due to the waste of resources. It's just for beginners that don't understand error handling.
Xeoncross
Yes, you can effectively catch everything up to but not including fatal errors:http://www.phpdevblog.net/2008/11/catching-warnings-and-notices.html
cballou
@Xeon: set_error_handler() and set_exception_handler(), when used in conjunction, will effectively deal with all of the above issues. This is the most universal way for handling any and all data. You just need a little trickery in the callback to determine which of the two cases you are handling.
cballou
A: 

I believe there is a philosophical difference between the definitions of errors and exceptions.

An error simply put is a programmed flaw, generated by a logical fallacy in the code. Passing strlen() an incorrect number of arguments should naturally be an error. An exception, on the other hand, handles those cases where everything is programmed correctly, but your code is interacting with resources outside of the codebase (filesystem, web service, external executable, etc). While it is expected that such external resources should work perfectly on every call, there will be cases -- out of the scope of your program's control -- that are not attributed to faults of your code (filesystem gets unmounted, connection timeout, etc). Because these issues are due to external factors, they are deemed exceptions.

The main difference is that an error occurs within one's own code, whereas an exception occurs in the case of an anomaly found in a third-party resource.

Kenaniah Cerny
This is not entirely true. Setting aside semantic debates of what the word "error" means, say you have some functions `A` and `B`, where `A` calls `B` with value `C`. `C` may be inappropriate for use with `B` -- as such, it is an *error*, a "logical fallacy in the code", to use your definition. But the error isn't in function `B`, it's in the function that passed `C` to `B` -- function `A`. So how can `B` signal to `A` that `A` has an error? Or, depending on your code, how can `B` signal to `Z`, the function that called `A`, that `A` has an error? That is what an exception is for.
Daniel Pryden
That sounds ok, but the fact that `A` was not programed to deliver the correct data type to `B` is not an exception - it's a "fallacy in the code". `A` should be re-written correctly to abide by the standards `B` has set. Now if `A` had no way of knowing what `B` wanted - that would be an exception.
Xeoncross