How to handle php notices, warnings and errors in REST api?
Let say, for example, that you are only concerned about fatal run-time errors, fatal compile-time errors and run-time warnings. Set the error reporting to desired level with error_reporting() function.
error_reporting( E_ERROR | E_COMPILE_ERROR | E_WARNING );
Since user-defined error handler ( later below ) can't handle fatal errors, fatal error messages will still be displayed. To avoid that use ini_set() function and set the display_errors
to zero.
ini_set( 'display_errors', 0 );
Now create a custom error handler with set_error_handler() to completely bypass PHP error handler for the error types specified ( does not apply to fatal errors ).
/* The following error types cannot be handled with a user defined function: * E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING * The standard PHP error handler is completely bypassed for the error types specified * unless the callback function returns FALSE. */function exception_error_handler( $severity, $message, $file, $line ) { if ( !( error_reporting() & $severity ) ) { // This error code is not included in error_reporting return; } // code for handling errors}set_error_handler( "exception_error_handler" );
Fatal errors can be handled on shutdown with register_shutdown_function(). Shutdown handler is executed after the script is done, or is terminated ( this also applies for errors ). We need to get the information about the last error that occurred ( error_get_last() ), next is to check if this is the type of error that we track ( that it is not really needed here since errors that are not specified in error_reporting
won't be triggered, but it can be useful to filter errors ), and lastly, call to exception handler.
function fatal_error_shutdown() { $last_error = error_get_last(); if ( error_reporting() & $last_error['type'] ) call_user_func_array( 'exception_error_handler', $last_error );}register_shutdown_function( 'fatal_error_shutdown' );
Now you can use custom exception handler to catch unhandled exceptions ( including fatal ones ) and to force the response code ( with header() function ).
Of course you can change HTTP status in PHP:
<?php header("HTTP/1.1 502 Bad Gateway");?>
You could change the message and the code, but you must to be careful with standard codes
set_error_handler
function is what I missed. I came up with the following code. Any better answer is welcomed.
function jsonErrorHandler(){ if (error_reporting()) { http_response_code(500); header('Content-Type: application/json; charset=utf-8'); $response = array_combine(['errno', 'errstr', 'errfile', 'errline', 'errcontext'], func_get_args()); die(json_encode($response)); }}set_error_handler('jsonErrorHandler');