Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you tell PHP to send headers (like 500) when an error occurs?

In my current project I'm querying PHP with normal HTTP-request but also via AJAX where I sometimes return JSON-formatted data and sometimes normal text. When an error occurs, in a normal request, you see the error-message and can do something about it. With AJAX-requests on the other hand you cannot be sure if you get an error or the data you want because it isn't displayed directly — you just run into troubles because your app won't work any more.

So I thought about an error-handling-system. My best idea is to send a 500 "Internal Server Error" header if an error occurs, so in my JS, when I send an AJAX-Request, I can simply check for errors that way and handle it.

Unfortunately PHP doesn't send that kind of header (like when you have a parse-error, or something in your code goes wrong) natively.

Can you:

a) Tell PHP to send headers like 500 if an error occurs? Or
b) Use set_error_handler to send a 500-header and then call PHP regular error handling? Or
c) Can you, in any other way send error headers when a PHP error occurs?

like image 418
Lukas Avatar asked Oct 27 '25 03:10

Lukas


2 Answers

i prefer using Exceptions for handling errors. First, you need to install error-to-exception error handler (http://php.net/manual/en/class.errorexception.php, example 1), then wrap your main application code in a try-catch block and send appropriate headers in the catch part. For example:

try {
    $myApplication->run();
} catch(Exception $e) {
   // log or otherwise register the error
   header('HTTP/1.1 500 Internal Server Error');
}

unfortunately, this doesn't work with so-called "Fatal errors", to handle these you have to use stupid tricks like this

ob_start();

register_shutdown_function(function() {
    $p = ob_get_contents();
    if(preg_match('~Fatal error~', $p))
        header('HTTP/1.0 500 Internal Server Error');
});

...your code... 
like image 128
user187291 Avatar answered Oct 28 '25 18:10

user187291


With AJAX-requests on the other hand you cannot be sure if you get an error or the data you want because it isn't displayed directly — you just run into troubles because your app won't work anymore.

Yes, you can.

Your XHR success callback fires when the transfer of data was successful. Given an application-layer logical error, that data might be some error message. Your success callback can and should parse the data it gets from the server, and determine whether there was an error.

So I thought about an error-handling-system. My best idea is to send a 500 "Internal Server Error" header if an error occurs, so in my JS, when I send an AJAX-Request, I can simply check for errors that way and handle it.

An "Internal Server Error" is generated when there's an error internal to your web server. You do not have an error internal to your webserver; you have a logical error within your application. Thus manually invoking such a status code is inappropriate.

Unfortunately PHP doesn't send that kind of header (like when you have a parse-error, or something in your code goes wrong) natively.

For the good reason above. There are different kinds of errors, and a PHP/application error does not prevent the webserver from doing its job. The HTTP request still succeeds (it just might not contain the information you were hoping for).

Think about a login form. When you try to login to Facebook but accidentally put in the wrong password, do you get a 500 Internal Server Error? No. You get a webpage, delivered properly with a 200 OK status code, whose text says somewhere "oops, you got your password wrong".

The above all said, I'll now answer your question.

a) Tell PHP to send headers like 500 if an error occurs? Or b) Use set_error_handler to send a 500-header and then call PHP regular errorhandling? Or c) Can you, in any other way sen error-headers when a PHP error occurs?

In all the above cases, whenever you want to send a status header, yes you can do this using the library header function.

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

You could write this in the error handler, or wherever you like.

What you can't do is control what happens when a PHP parse error occurs. Your application is going to have to assume that you have tested all your PHP scripts and that they parse; this doesn't seem like a difficult thing to guarantee.

like image 35
Lightness Races in Orbit Avatar answered Oct 28 '25 17:10

Lightness Races in Orbit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!