views:

59

answers:

1

Hi all.

I am running Apache 2.2.15 with PHP 5.3.2, 'display_errors' disabled, 'display_startup_errors' disabled, 'log_errors' enabled.

At my setup (so I consider it a norm), PHP aborts on fatal errors, which is good, and sets HTTP status code to 500. Fatal errors include E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR and, probably, E_RECOVERABLE_ERROR (cannot trigger it myself, so can't easily check what happens). I think it is a good idea that it does set the code to 500, because I think it is the right thing to do - obviously if your script contains syntax errors and/or fails to do what is supposed to do at runtime, it is a server error, if we consider PHP part of the server.

Now, here is the important part:

Anyway, I have now installed XDebug to track errors better, but I can see that now, no matter the error, even though the script aborts as before on fatal errors, the HTTP status code is always 200. This breaks my client that 'talks' to Apache/PHP via HTTP :|

Also, setting display_errors to On/1, makes PHP no longer set HTTP status code to 500 and exhibits exactly the same behavior as with XDebug above.

I am very much dependent on reliable status code behavior here, and this all leads me to believe it's some kind of fluke or random like weather.. or am I missing something?

UPDATE

There is a blog post which oulines the issue: http://talideon.com/weblog/2008/02/php-errors.cfm

For my part, I have disabled XDebug, seeing as it is what causes the bad behavior in the first place. I only used it for stack tracing anyway, and now use a custom error handler for that instead. Also, the linked article is from 2008, apparently PHP does set HTTP status code to 500 automatically these days. It does so here. Without XDebug, of course.

+1  A: 

I assume you are using a custom error handler to emit the 500.

I don't know XDebug that well, but according to this article, it registers its own error handler, probably overriding yours in the process:

Please note that the extended error display of xdebug does not work if you define a custom error handler using register_error_handler(). This is because xdebug internally uses the same mechanism. Should your scripts use a custom error handler, you can still use the function xdebug_get_function_stack() to output the stack trace in your custom error handler.

However, for production use, you are not going to activate XDebug anyway, are you?

As for why a 200 is output when you activate display_errors(), that I don't understand. Can you post your custom error handler function to look at?

Pekka
Nonono, I don't emit anything! I want PHP to set the code to 500 whenever an error occurs, regardless whether I myself triggered it or something went wrong with parsing or running the script.Even though for production I won't activate it, I can't work with my scripts when XDebug is enabled because the status codes are broken, which means I can either test using "release" profile or debug without XDebug.I don't have any custom error handler, why do you think I have one? :-)
amn
Pekka, I found someone expressing himself much better than me on exactly the same issue I have: http://talideon.com/weblog/2008/02/php-errors.cfmI wonder if this has been solved since. I mean, is the guy totally on point here or what!
amn
@amn interesting and surely a good point! But how are you *currently* making PHP emit the 500 error? Is there an INI setting?
Pekka
No, that's the thing - apparently since the linked post, PHP devs have come to their senses, because my PHP (5.3.2) **does** set HTTP code to 500 on errors. But once I enable XDebug, it's back to 200 OK no matter what. I have now disabled XDebug, and use a custom error handler that prints the stack (all I needed in XDebug anyway). Maybe I'll edit the original question to reflect the changes.
amn
@amn yeah, do edit it, that PHP emits a 500 automatically is news to me, interesting to know!
Pekka
Pekka, would you be so kind as to try it yourself? Just to confirm my PHP is not going weirding ways? I swear, I saw it once give me a 200 OK on a fatal error (no error handler, display {startup} errors=off). I am becoming religious here, as my client depends on proper status codes.
amn
@amn I have only 5.3.1 at my disposal right now (Apache 2.2, Windows 7). I consistently get 200 s no matter what I do - parse errors, syntax errors, user errors etc. Display_errors is on.
Pekka
However, I can't find any mention of this in the 5.3.2 changelog: http://php.net/ChangeLog-5.php odd. Are you sure there is no other extension installed that could cause this?
Pekka
Update: I have seen it said that when display_errors is turned to 0, throwing a 500 is indeed PHP's default action. But I can't find this documented anywhere on the PHP site.
Pekka
I asked a question about it: http://stackoverflow.com/questions/3075355/php-emitting-500-on-errors-doc-links
Pekka
Pekka, like I said, you will get 200 OK when display_errors is on. I do too. It seems that PHP considers errors no longer errors if these are sent to output :-) But I see you are up to the fact, but just in case..
amn
@amn Cheers, I understand now. Gordon's link in the other question pretty much explains it I think. I guess XDebug is interfering in some way so PHP thinks it's not an empty page any more, even if it is. I think this can be sorted reliably only through a custom error handler that does the `header("HTTP/1.1 500 Internal Server Error");` for you - even though it may be worth filing your findings as a bug. The question is just where: PHP or XDebug? It would have to be both at first...
Pekka