How can I get php to return 500 upon encountering a fatal exception?

PhpError HandlingError Code

Php Problem Overview


PHP fatal errors come back as status code 200 to the HTTP client. How can I make it return a status code 500 (Internal server error)?

Php Solutions


Solution 1 - Php

header("HTTP/1.1 500 Internal Server Error");

Solution 2 - Php

This is exactly the problem I had yesterday and I found solution as follows:

  1. first of all, you need to catch PHP fatal errors, which is error type E_ERROR. when this error occurs, script will be stored the error and terminate execution. you can get the stored error by calling function error_get_last().

  2. before script terminated, a callback function register_shutdown_function() will always be called. so you need to register a error handler by this function to do what you want, in this case, return header 500 and a customized internal error page (optional).

    function my_error_handler() { $last_error = error_get_last(); if ($last_error && $last_error['type']==E_ERROR) { header("HTTP/1.1 500 Internal Server Error"); echo '...';//html for 500 page } } register_shutdown_function('my_error_handler');

Note: if you want to catch custom error type, which start with E_USER*, you can use function set_error_handler() to register error handler and trigger error by function trigger_error, however, this error handler can not handle E_ERROR error type. see explanation on php.net about error handler

Solution 3 - Php

Standard PHP configuration does return 500 when error occurs! Just make sure that your display_errors = off. You can simulate it with:

ini_set('display_errors', 0); 
noFunction();

On production display_errors directive is off by default.

Solution 4 - Php

I have used "set_exception_handler" to handle uncaught exceptions.

function handleException($ex) {
      error_log("Uncaught exception class=" . get_class($ex) . " message=" . $ex->getMessage() . " line=" . $ex->getLine());
      ob_end_clean(); # try to purge content sent so far
      header('HTTP/1.1 500 Internal Server Error');
      echo 'Internal error';
    }

set_exception_handler('handleException');

Solution 5 - Php

Since PHP >= 5.4

http_response_code(500);
echo json_encode( [ 'success' => false , 'message' => 'Crazy thing just happened!' ]);
exit();

Please set the httpCode before echo.

Solution 6 - Php

It is not possible to handle PHP E_ERROR in any way according to the PHP documentation: http://www.php.net/manual/en/function.set-error-handler.php

Nor is is possible to handle "E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT" according to that link.

You CAN provide a handler for the other error, warning, and notices including E_USER_ERROR, but that's really not as useful as it sounds since this error only gets thrown intentionally by the programmer with trigger_error().

And of course you can catch any Exception (even the ones thrown by the native PHP functions).

I agree that this is a problem. Servers should NOT return 200 OK when application code crashes and burns.

Solution 7 - Php

You can use php error handling

http://www.w3schools.com/php/php_error.asp

Solution 8 - Php

You would have to catch the thrown error using try/catch and then use that catch block to send a header() with the 500 error.

try {
    ...badcode...
	throw new Exception('error');

} catch (Exception $e) {

	header("Status: 500 Server Error");
	var_dump($e->getMessage());
}

If the fatal exception is not surrounded by try {} catch blocks then you must register a global handler and use register_shutdown_function() to check for an error at script end.

Solution 9 - Php

Never forget to set header("HTTP/1.1 200 OK", true, 200); as the last line of any execution path:

//first things first:
header("HTTP/1.1 500 Internal Server Error", true, 500);


//Application code, includes, requires, etc. [...]


//somewhere something happens
//die();
throw new Exception("Uncaught exception!");


//last things last, only reached if code execution was not stopped by uncaught exception or some fatal error
header("HTTP/1.1 200 OK", true, 200);

In PHP 5.4 you can replace the header function above with the much better http_response_code(200) or http_response_code(500).

Solution 10 - Php

The hard thing when dealing with fatal errors (compile errors, for example a missing semicolon) is that the script won't be executed, so it won't help to set the status code in that script. However, when you include or require a script, the calling script will be executed, regardless of errors in the included script. With this, I come to this solution:

rock-solid-script.php:

// minimize changes to this script to keep it rock-solid
http_response_code(500); // PHP >= 5.4
require_once("script-i-want-to-guard-for-errors.php");

script-i-want-to-guard-for-errors.php:

// do all the processsing
// don't produce any output
// you might want to use output buffering

http_response_code(200); // PHP >= 5.4

// here you can produce the output

Direct your call to the rock-solid-script.php and you're ready to go.

I would have liked it better to set the default status code to 500 in .htaccess. That seems more elegant to me but I can't find a way to pull it off. I tried the RewriteRule R-flag, but this prevents execution of php altogether, so that's no use.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMikeView Question on Stackoverflow
Solution 1 - PhpChris Jester-YoungView Answer on Stackoverflow
Solution 2 - PhpfuyiView Answer on Stackoverflow
Solution 3 - PhplukyerView Answer on Stackoverflow
Solution 4 - PhpMatti HaavikkoView Answer on Stackoverflow
Solution 5 - Phpvanduc1102View Answer on Stackoverflow
Solution 6 - PhpJonathan HansonView Answer on Stackoverflow
Solution 7 - PhpXinusView Answer on Stackoverflow
Solution 8 - PhpXeoncrossView Answer on Stackoverflow
Solution 9 - PhpTiberiu-IonuČ› StanView Answer on Stackoverflow
Solution 10 - PhpRemco NijhuisView Answer on Stackoverflow