views:

477

answers:

4

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?

+1  A: 

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;
?>
konforce
Custom error handlers can't catch fatal errors (e.g. call to method on a non object; time limit/memory limit exhausted) or parse errors. From the docs: `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` http://php.net/set_error_handler
Frank Farmer
Yes, that's worth mentioning. I wasn't assuming he meant fatal literally, as some people use it to mean any type of error that cannot be recovered from.
konforce
:D i really do mean fatal error XD
Jeffrey04
Then you'll need to disable ALL output buffering and refrain from displaying any data until the end of the script (as my edited answer shows) or default to a 500 code and adjust to 200 on success (as others have suggested).
konforce
+3  A: 

One possible way (dodgy, untested) would be to set the default response to 500, if everything executes successfully set the response to 200

Ben Rowe
Throw in a large page buffer to prevent the infamous error about output already started and that should do it.
TheJacobTaylor
That, or make sure that you put `<?php header('500 Internal Server Error'); ?>` at the beginning of your script rather than before the tricky part.
Christian Mann
+1  A: 

I would think that you'd want to catch and fix all Fatal errors before deploying the application, since many of them are code errors, missing includes, non-existent objects, which are all development errors. Even out-of-memory errors can be minimized against with coding techniques that are memory frugal (one of the biggest wins is using unbuffered queries and processing the data and emitting output as the resultset is returned, instead of throwing around huge arrays).

staticsan
yea, I should, but it is kinda annoying during development
Jeffrey04
A: 

not sure if this is helpful, but posting anyway http://php.net/manual/en/function.register-shutdown-function.php

Jeffrey04