In my homemade PHP MVC framework, I've written a little error handler that wraps PHP errors in an exception, then throws it.
class ErrorController extends ControllerAbstract {
...
public static function createErrorException($number, $message = NULL, $file = NULL, $line = NULL, array $context = array()) {
throw new ErrorException($message, $number, 0, $file, $line);
}
}
Which is then registered using set_error_handler()
. This works fine, with the exception (no pun intended) of fatal errors. My custom error handler is still called, but I can't catch the ErrorException
that is thrown.
An example of such an error would be trying to include a file that doesn't exist:
try {
require 'Controller/NonExistentController.php';
} catch (ErrorException $exc) {
echo $exc->getTraceAsString(); // code never reaches this block
}
My custom error handler is called and the exception is thrown, but the code never reaches the "catch" block. Instead, PHP generates HTML (bad!):
Warning: Uncaught exception 'ErrorException' with message 'require(Controller/NonExistentController.php): failed to open stream: ...
Followed by:
Fatal error: Program::main(): Failed opening required 'Controller/NonExistentController.php' (include_path='.:') in ...
I do not want to attempt recovering from a fatal error, but I do want my code to exit gracefully. In this instance, that means sending back an XML or JSON response indicating an internal error, because this is a REST application and that's what my clients expect. HTML responses would most likely break the client applications as well.
Should I go about this differently?
Look at documentation about require
on php.net:
require is identical to include except upon failure it will also produce a fatal E_COMPILE_ERROR level error. In other words, it will halt the script whereas include only emits a warning (E_WARNING) which allows the script to continue.
In your case you can handle fatal errors with help of register_shutdown_function
, which requires PHP 5.2+:
function customFatalHandler() {
$error = error_get_last();
if( $error === NULL) {
return;
}
$type = $error["type"];
$file = $error["file"];
$line = $error["line"];
$message = $error["message"];
echo "Error `$type` in file `$file` on line $line with message `$message`";
}
register_shutdown_function("customFatalHandler");
Also this can be helpfull for you
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