Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch PHP Fatal Error

I have a web service site that is restful enabled, so other websites/ajax script can make a call to the site to get/set data. However, whenever the web service site somehow returns a PHP fatal error, the HTTP status that is returned is 200 instead of 500. Is there a way to fix it so that whenever a fatal error occurs, returns 500 instead of 200? Or, if it is not possible, how can I change my client to recognize the fatal error returned by the webservice?

like image 471
Jeffrey04 Avatar asked Feb 25 '10 04:02

Jeffrey04


People also ask

Can we catch fatal error in PHP?

In PHP 7, fatal errors are now exceptions and we can handle them very easily. Fatal errors result in an error exception being thrown. You need to handle non-fatal errors with an error-handling function. Here is an example of catching a fatal error in PHP 7.1.

What is PHP fatal error type?

A fatal error is another type of error, which is occurred due to the use of undefined function. The PHP compiler understands the PHP code but also recognizes the undefined function. This means that when a function is called without providing its definition, the PHP compiler generates a fatal error.

How can I get 500 error in PHP?

You can solve the PHP error 500 by temporarily deleting the misconfigured htaccess file. The 500 error can go away by increasing the values set for the max_execution_time and the memory_limit settings. Setting the file permission to 644 or 755 can help in resolving the 500 internal server error.


3 Answers

PHP does send a HTTP 500 on a Fatal error.
Let me cite a comment in this PHP bug-report (a xdebug bug prevents this behavior):

It does happen. It requires that:

1) display_errors = off
2) No headers have been sent yet by the time the error happens
3) Status is 200 at that time.

<?
    ini_set('display_errors', 0); 
    foobar();
    // This will return a http 500
?>

You can catch fatal errors with a shutdown function and error_get_last:

register_shutdown_function(function() {
    $lastError = error_get_last();

    if (!empty($lastError) && $lastError['type'] == E_ERROR) {
        header('Status: 500 Internal Server Error');
        header('HTTP/1.0 500 Internal Server Error');
    }
});
like image 131
Benjamin Cremer Avatar answered Oct 03 '22 16:10

Benjamin Cremer


One possible way would be to set the default response to 500, if everything executes successfully set the response to 200:

http_response_code(500);
render_my_page();
http_response_code(200);
like image 41
Ben Rowe Avatar answered Oct 03 '22 17:10

Ben Rowe


Create a custom error handler (set_error_handler) and call header("HTTP/1.0 500 Service not available");.

Edit:

Per the first comment to my answer, you cannot trap true fatal errors. However, PHP will default to setting a 500 error code on fatal errors if output buffering is disabled and errors are not displayed to the screen.

<?php
        $x = y();
?>

The above code will return a 500 error code if nothing has been sent to the screen.

So if you want this kind of error to set the proper code, do your own buffering:

<?php
        $buffer = 'blah';
        $x = y();  // will trigger 500 error
        echo $buffer;
?>
like image 25
Matthew Avatar answered Oct 03 '22 17:10

Matthew