I'm a relative newbie to PHP, but it seems to me that PHP's error handling is a bit of a ghetto, with errors and warnings interspersed with exceptions (and don't get me started on die()
). As such, I'm not certain how best to go about creating, interpreting, and handling all error cases in my application.
My general plan of attack is roughly as follows:
set_error_handler()
to wrap the errors as they come.try/catch
blocks will be in place when needed, to handle exceptions I don't throw myself.index.php
point-of-entry file) in it's own try/catch
. Should that fail, I'll throw an HTTP 500
and show a suitable error page. Presumably this page will be a single, pre-compiled file rather than a collection of header/body/footer includes - this is largely so that I can still cover weird exceptions like a garbled template file. I assume this is why Google's 500-class error page looks so much different from everything else they put out.CriticalErrorException
- that can be identified directly in my logs/spawn an email so I can look into it quickly. In general, I'm expecting these to be things that may happen in dev, but should be ironed out by production.I think this covers most cases pretty well, but as I said I'm very new to PHP so I don't know if there are corner cases or weird behaviours that I'm overlooking.
What are the flaws in my plan? How can I overcome them?
Overall, the strategy of letting unexpected exceptions bubble up to a top catch
block and then serve out a HTTP 500
is fine (many frameworks do just that).
I don't quite agree with making a CriticalErrorException
-- maybe you don't expect to catch something now, but you might expand your error handling in the future (possibly in the face of additional application requirements). Just throw whatever is natural. A simple Exception
is fine in most cases.
Regarding PHP errors: you do not strictly need to convert E_ERROR
into an exception (it will kill your app anyway, and will show up in the error log as well). You would do well to handle E_NOTICE
though, as notices almost always mean that there's something not right with the code.
Finally, when talking about PHP functions that raise warnings, I would go with this:
// Assume that php_function() raises E_WARNING and returns FALSE on error
// WARNING: if you have defined a custom error handler, IT WILL STILL BE CALLED
// even though the @ operator suppresses the error
$result = @php_function($argument); // suppress error
if (!$result) {
// error handling here
}
instead of this:
try {
$result = php_function($argument);
}
catch (Exception $ex) {
// error handling here
}
The reason being that converting to an exception doesn't really buy you anything when you intend to react to the error immediately. On the contrary, the first code snippet will "tell" a developer reading it to look up the documentation for php_function
if more info on its error handling strategy is needed. The second code snippet will require the developer to have knowledge about error handling specifically as implemented in your app.
Update:
I 'm not saying that you should use @
to just ignore errors coming out of function calls. What I am saying is that, when using legacy PHP functions that behave this way, and when you are fully prepared to handle the error and recover from it, then of course it should no longer be considered an "error" regarding your application's execution. In this specific case, I recommend suppressing it so that it doesn't get reported as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With