Are there any "gotchas" with this approach to handling errors in PHP?
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 applicati开发者_StackOverflowon.
My general plan of attack is roughly as follows:
- Convert all warnings/errors into Exceptions, using
set_error_handler()
to wrap the errors as they come. - Code defensively, preemptively checking for things I expect to go wrong. Throw exceptions only when I can't handle the error directly. Usual
try/catch
blocks will be in place when needed, to handle exceptions I don't throw myself. - Wrap my entire application (i.e. my
index.php
point-of-entry file) in it's owntry/catch
. Should that fail, I'll throw anHTTP 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. - As a corollary to #2 and #3, since I'm expecting to handle everything upfront, if I decide to throw my own exception, I'm also expecting not to catch the error, and instead let it bubble all the way up to my top level handler. The thinking here is that if I can't handle it when it happens, I'm probably ill-equipped to handle it anywhere else. I'm thinking of giving these errors their own subclass - perhaps
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. - Any error that makes it to the top gets logged in the database, with failover to a log file. Critical errors, as indicated above, trigger an email. If the reporting fails over to the file - i.e. there's a DB error - that would also trigger an email.
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.
精彩评论