php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38184 JSON needs set_error_handler to capture all error types
Submitted: 2006-07-22 10:23 UTC Modified: 2006-07-26 00:04 UTC
Votes:10
Avg. Score:4.7 ± 0.5
Reproduced:8 of 9 (88.9%)
Same Version:5 (62.5%)
Same OS:4 (50.0%)
From: shelby at coolpage dot com Assigned:
Status: Wont fix Package: Output Control
PHP Version: 4.4.2 OS: Irrelevant
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2006-07-22 10:23 UTC] shelby at coolpage dot com
Description:
------------
A new issue that should re-open bug #12136:

http://bugs.php.net/bug.php?id=12136

When server-side output is header( "Content-type: application/json" ), when the client is receiving input via XHttpRequest::responseText, then server-side all error types need to be captured and converted to JSON output, else client needs to do special detection to handle other inpyt Content-types.

By default, PHP server-side outputs errors in "Content-type: text/html".  Thus the client will need to detect these using XHttpRequest::getResponseHeader() and assume they are always errors.  This client assumption that all "text/html" input are errors is logically inconsistent (not OO).  Rather the correct programming construct is that errors should be encoded server-side as JSON output, so that client can logically detect errors not by Content-type, but by an encoding which specifically identifies them as errors.

Also this would enable presentation of errors in alert(), not forcing them to be presented in HTML.

The justification "by design" in Bug #12136, makes the point that the engine may be unstable after the occurrence of certain errors and thus implying that allowing user callback handling could be unreliable.  Hmmm.  Lesser of evils?  Seems to me that if the engine is stable enough to write out the error in HTML, then should a simplistic user function to write out the error in JSON (or whatever) be less stable?

Instead of allowing all error types in set_error_handler(), should error_reporting() have an optional input argument for "Content-type" and support minimally XML and JSON?

This bug report is very important for the Web2.0/AJAX revolution.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-07-22 12:00 UTC] shelby at coolpage dot com
Detecting the "Content-Type" with XMLHttpRequest::getResponseHeader() is not a workaround, because PHP's built-in error output does not override the header( "Content-type: application/json" ) set by the PHP script.

So the workaround gets even more bizzare, with the client having to parse the XMLHttpRequest::responseText for JSON syntax errors to determine it isn't JSON.  <sarcastic>What a wonderfully reliable form of error reporting</sarcastic>!

For now my workaround is I make sure the 1st char of JSON server-side output is "{", then client side I do XMLHttpRequest::responseText.chatAt( 0 ) != "{" to detect that a PHP error has been received instead of JSON.

Correct typo: I meant XMLHttpRequest, not XHttpRequest.
 [2006-07-22 12:04 UTC] shelby at coolpage dot com
Obviously the workaround does nothing for the case where the "{" has already been output (or if PHP decides to output "{" as first char of it's errors), and then PHP generates an HTML error into the middle of the JSON output.

I guess the more reliable client side workaround should use a full JSON parser.
 [2006-07-23 06:37 UTC] shelby at coolpage dot com
Someone changed this bug to to Feature Change Request.  I have changed it back to Output Control bug, because currently there is no way to prevent error_reporting from outputting content which violates (a BUG) the header( "Content-Type..." ) of the script (when it is not "text/html"), except to turn error_reporting off.

Sorry to say, this is a bug, as it can cause the client web app to function incorrectly, or it can cause the reporting error to be not reported.  There is no generalized workaround possible (if the error is generated in middle of non-"text/html" content), other than to turn off error reporting.  How could you not define this as a bug?
 [2006-07-23 06:45 UTC] shelby at coolpage dot com
Even applying full JSON parsing (or any "Content-Type" parsing) will not workaround the problem, because if the error occurs in the middle of the content, the client will be unable to extract the error message and present it.  Thus error reporting is effectively off.

That is why I say the only generalized workaround is to turn off error reporting.  Thus it is a bug that turns off error reporting in generalized case.  How is turning off error reporting less reliable than allowing set_error_handler to attempt process all error type (even if engine has become unstable)?

The generalized fix would be to fix the engine so that it is not rendered unstable by errors.  One would think you already have achieved such, given the existence of try-catch error trapping.

Seems the limitation placed on set_error_handler is now unnecessary?
 [2006-07-23 07:08 UTC] tony2001@php.net
Zeev gave pretty good explanation why it won't happen.
 [2006-07-23 07:26 UTC] shelby at coolpage dot com
Are you referring to Zeev's comments in bug #12136, that the engine may be unstable after certain errors?

Then how do you explain the existence of catch{} recovery after try{} blocks?  How is the engine able to be stable enough to run user code in the catch{} block?  Even if we are talking about parsing errors (script is not yet executing), why can't the set_handler_error input function be parsed separately and run in a separate process?

Now back to logic 101:

(A) Let's assume the PHP/Zend engine can not be made stable after E_ERROR type errors, so the result for the case of this bug is "no error reporting" (of E_ERROR type errors) and unexplained crash of script. 

(B) Whereas if we enabled set_error_handler to capture E_ERROR, then in cases where the engine was not too unstable, the error would get reported and the script would die with explanation reported.  In cases where engine was too unstable and set_error_handler crashed, then we still get the result of #A.

Thus logic 101 says that #B is superior.

Sounds to me the bug is something that you (the person changing this to "Won'd Fix") doesn't want to work on, versus being something impossible to fix?
 [2006-07-23 07:59 UTC] tony2001@php.net
>Then how do you explain the existence of catch{} recovery
> after try{} blocks?
First of all, there are NO catch/try blocks in 4.4.2 (and this is the version you specified).
Second, try/catch block never did catch any errors at all, they are for exceptions only.
Third, E_FATAL/E_ERROR errors are completely different from exceptions and no wonder engines state is different too.

>Thus logic 101 says that #B is superior.
My logic says that we don't want the engine to crash and we prefer to get a nice error message instead in case if your code is completely wrong and is not going to work.

>Sounds to me the bug is something that you (the person
> changing this to "Won'd Fix") doesn't want to work on,
> versus being something impossible to fix?
We would gladly review your patches.
 [2006-07-23 08:52 UTC] shelby at coolpage dot com
"...we don't want the engine to crash..."

By the time the script has been terminated by an error, it logically already has effectively crashed.  Each script runs in it's own process, so if the engine crashes for a script while processing user error reporting code, only that process of the engine crashes, thus effectively this is the same as the script ending.  Thus my logic 101 applies.


"...NO catch/try blocks in 4.4.2..."

There are in PHP5.  Are we trying to go backwards or get a solution?


"...E_FATAL/E_ERROR errors are completely different from exceptions..."

I repeat: "Even if we are talking about parsing errors (script is not yet executing), why can't the set_handler_error input function be parsed separately and run in a separate process?"


"...We would gladly review your patches..."

a) Then why is this bug marked "Won't Fix"?
b) Why not just say "don't report bugs to us that we don't want to hear about"?
c) Miraculously "Won't Fix" bugs fall into a blackhole and are not displayed on your stats page, so public is unaware of how many bugs you won't fix:

http://bugs.php.net/bugstats.php
 [2006-07-23 09:00 UTC] shelby at coolpage dot com
"...we prefer to get a nice error message instead..."

The nice error message ends up in corrupted output that the client does not understand and thus can not display, thus that nice error is lost and program can not be fixed, because user is unable to report the error to programmers.

In short, the application just fails silently with a Javascript error in the client.

I think you need to take some more time to understand the problem, before jumping to "Won't Fix".
 [2006-07-23 09:49 UTC] mike@php.net
Why don't you just disable display_errors instead of spending your time with this monologue?
 [2006-07-23 12:49 UTC] shelby at coolpage dot com
"...Why don't you just disable display_errors..."

How many times do I have to repeat what I already wrote, "...or it can cause the reporting error to be not
reported...other than to turn off error reporting..."

The point is that this bug effectively causes error reporting to not occur for JSON (or other Content-Types) output.  Whether that is accomplished via corrupted output or via error_reporting( 0 ) is besides the point.

The point being that without error reporting, users of the application will get silent failure.  That is why error reporting exists in the first place.  Error reporting is a fundamental aspect of robust programming.

Your fix to a bug is mark it as "Won't Fix", tell the programmer to turn off error reporting, and the accuse the bug reporter of typing a "monologue"??

Wonderful.
 [2006-07-23 12:54 UTC] shelby at coolpage dot com
"...instead of spending your time with this monologue..."

So reporting bugs to you is a waste of our time?

We should stop reporting bugs?

100% nonsense.
 [2006-07-25 23:57 UTC] shelby at coolpage dot com
From:  "Jon Meyer" <jonmeyer at gmail dot com> 
Subject:  error reporting in PHP 
Date:  Tue, July 25, 2006 7:38 pm 
To:  shelby at coolpage dot com 

--------------------------------------------------------------------------------


I saw your bug 38184, but its closed so I can't comment on it there.

My thought was that you could propose an alternative mechanism for
doing what you want (encoding error responses in JSON):

What if there was a

    set_fatal_error_redirect('error.php');

For fatal errors, instead of trying to continue evaluating the current
request (engine may be in an unstable state etc) the PHP engine could
collect the output it was going to print to the client, create a new
evaluation context and then evaluate the contents of the error.php
essentially as if it were a new request - passing the error output in
as the value of a global variable e.g. $_SERVER['error']That way you
could write an error.php like:

<?php
function jsonEncode($str) { ... }

print "{"error":\"" . jsonEncode($_SERVER['error']) . "\"}";
?>

I've seen other servers which handle errors using the "redirect"
concept - it may fly better than trying to fix set_error_handler.

Jon
 [2006-07-26 00:04 UTC] shelby at coolpage dot com
Thanks Jon.  Imho, your suggestions are practical ways to accomplish my prior notion, "...why can't the set_handler_error input function be parsed separately and run in a separate process?...".

Too bad the PHP developers closed this bug prematurely.  Any one else who wants to contribute to this bug report, just email me and I will post your comments to this bug report if warranted.

Thanks.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 18:01:58 2014 UTC