Tuesday 17 July 2018

Capturing and Handling PHP Errors Gracefully

Capturing and Handling PHP Errors Gracefully

Capturing errors are essential in reducing bugs and debugging PHP code. Whether it’s a simple undefined variable or a more complex memory allocation error, it’s important that you are made aware of these errors. Not only that but if a frontend user sees an error, or if something doesn’t work as it should, it can instantly effect their view of your website or application, sometimes even putting them off enough to move on elsewhere. Remember that even though you’ve tested your code thoroughly there will always be a scenario that you haven’t tested. You can be sure that if there’s an error a user one day will find it.
Another scenario I ran into recently was where a script was running silently as a background process. Due to a fatal error somewhere whilst it was running the script stopped suddenly and, due to it running silently I was unaware that anything had gone wrong for a good few hours.
So, how do we capture these errors? Allow me to show you…
The Solution
To deal with these errors appropriately I’m going to use two PHP functions; register_shutdown_function() and error_get_last().
The first function, register_shutdown_function(), allows us to specify a function that will be executed as soon as the PHP script stops running, whether it be from finishing naturally due it coming to the end, or failing because of a fatal PHP error.
The second function, error_get_last(), will pass back the last error, if any, that occured during the running of the script. By putting these two functions together we can create a pretty nifty way of detecting why a script might of failed. Allow me to show you some examples:
Handle All Errors

  1. register_shutdown_function('handleErrors');  
  2.   
  3. function handleErrors() {  
  4.       
  5.    $last_error = error_get_last();  
  6.   
  7.    if (!is_null($last_error)) { // if there has been an error at some point  
  8.   
  9.       // do something with the error  
  10.       print_r($last_error);  
  11.   
  12.    }  
  13.   
  14. }  
Should an error occur, the above code would output an array containing information about the last error encountered like so:
  1. Array  
  2. (  
  3.     [type] => 8  
  4.     [message] => Undefined variable: myVar  
  5.     [file] => C:\www\index.php  
  6.     [line] => 24  
  7. )  
Handle Only Fatal Errors
The above example might be a bit overkill for a lot of developers due to the fact it will return any type of error, including simple undefined errors. What about if we only want to know about fatal PHP errors that caused the script to stop running completely? Then try this:

  1. register_shutdown_function('handleErrors');  
  2.   
  3. function handleErrors() {  
  4.       
  5.    $last_error = error_get_last();  
  6.   
  7.    if (!is_null($last_error) && $last_error['type'] === E_ERROR) { // if there has been a fatal error  
  8.   
  9.       // do something with the error eg. email it, log it somewhere  
  10.   
  11.    }  
  12.   
  13. }  
I’ve found that by using the above snippets I’ve managed to iron out lots of bugs and errors that I was completely unaware of. You can bet your bottom dollar that a user wouldn’t report an error if they encountered one so this allows me to act on their behalf and deal with any problems that arise.

0 comments:

Post a Comment