Send PHP errors through JSON - php

I am trying to debug a page that sends emails with attachments via ajax and when PHP kicks out an error, I get "Parse Error" because the error is not being sent back via JSON. Is there anyway to wrap up the PHP errors so I can alert them and see exactly what PHP errors are coming up?
What I am hoping to see in the js alert is the same thing you would see printed on the screen if this form was not submitted using ajax.

Use HTTP status codes. Simple and clean.
On the client side: You can handle the HTTP states with the success and failure callbacks of the common JavaScript frameworks.
On the server side: Use exceptions and handle them with a catch block. In the catch block set the HTTP status code and echo the exception message. Or use the less fancy set_error_handler() function and set the status code and error message in the callback function.

Fatal errors usually can't be handled *.
Try improving your code and just don't make parse errors or other fatal errors. Handling warnings and notices is easy: http://php.net/manual/en/function.set-error-handler.php
*: It's possible but it takes a lot of effort.

function json_error($msg) {
header('HTTP/1.1 500 ' . $msg);
die(json_encode(array('error' => $msg)));
}
json_error('something bad happened');
This will trigger the error: ajax callback on the JS side.
echo json_encode(array('anything' => 'really', 'any key' => 'any value'));
Will trigger the success: callback.

You'd use exception-handling, look here: http://www.php.net/manual/en/language.exceptions.php

Related

Capture PHP error body within jQuery AJAX

I have an AJAX build that functions like a CMD line box. It allows me to breakup and scrub 100,000+ line CSV files on servers where MySQL 'IMPORT from FILE' is disabled. That "scrub" process is different for every client. Therefore I have built this tool to allow me to include various PHP scripts
It works great except for error handling in 1 area: the PHP error level.
I want to log the error using JS, specifically console.log()
consider then the following JS
$.ajax({
type: 'POST',
dataType: 'text', //also tried json
url: PHP_SCRIPT, //for sake of referance
data: $.param(data), // param object values as POST values
cache: false,
error: function(error) {
console.log("fubar:" + JSON.stringify(error));
If I cause an error in PHP_SCRIPT (that is not handled using try/catch and output as JSON) then I get the following "ambiguous" reply
stringify:{"readyState":4,"responseText":"","status":500,"statusText":"error"}
Here is the problem: responseText is empty.
What is really happening in PHP_SCRIPT is this error:
Fatal error: Uncaught UnexpectedValueException: RecursiveDirectoryIterator::
Which I can of course see if I run the PHP script (and I know why its happening, my question is not about the RDI error). Consider it could be other errors as well: a failed include, a mistake in code, ect. But JS and jQuery AJAX do not seem to "capture" the body of the failed PHP script.
GOAL: I want to "capture" PHP errors and show them using console.log() (or even my makeshift CMD line box) so I do not have to cut up the PHP_SCRIPT's and debug each line separately. I do not understand why error.responseText does not capture the output.
Ideally - the PHP "Fatal error" above should have been captured as TEXT and output in the log.
Note: I have PDO try/catch handling for the DB queries where I can output a success.error object and handle it appropriately, catching the PDO exception and log it to the console. Alas, I see no useful way to handle other PHP errors (such as a failed include or other common PHP mistakes). If it matters- I am using WordPress Admin AJAX with nonce and die() and my scripts work great, but during dev of new scripts catching errors is annoying.
Question Summary:
Is there a way to catch all/any PHP errors that are not output as JSON and console.log them when $.ajax - error happens?
Is there some way to capture the 'body' of the PHP error and console.log it?
Thank you for your consideration in this matter
UPDATE---
Added video to clarify: http://www.screencast.com/t/ZyCeaMyAxBO
Something like this will capture all uncaught exceptions and output a message in JSON format.
set_exception_handler(function($e) {
$msg = "Error: ";
// maybe you want to treat some differently?
if ($e instanceof \PDOException) {
$msg = "Database error: ";
}
// you can access all properties of the exception to build a reply
$msg .= $e->getMessage();
header("Content-Type: text/json");
echo json_encode(["message" => $msg]);
});
You can't catch ALL error situations, basically because you'll have to write the error handler in PHP and some errors (like parse errors) cause that the script doesn't even compile and therefor cannot be executed at all.
But with set_error_handler() / set_exeception_handler() you can probably cover a good portion...

jquery + php: catching php error from ajax

i am using jquery's $.post and the server script sometimes will raise a php error.
any ideas how i could catch that error and report it back to the client script?
i have tried set_error_handler() but unfortunately for some reason it doesn't work on fatal php errors, so when there's an error simply nothing will happen. thanks
The best way to do this is to have the script always return json and have a success:true/false in it, then you will never need the error handler.
I know you can't always do that so according to the docs you can do this found here:
var jqxhr = $.post("example.php", function() {
alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
// perform other work here ...
// Set another completion function for the request above
jqxhr.complete(function(){ alert("second complete"); });
Update
With xml:
<root>
<success>true/false</success>
<response>
<response_node_1>Foo</response_node_1>
<response_node_2>Bar</response_node_2>
</response>
</root>
You can't track fatal errors from within the same PHP script. As you write set_error_handler is not working on those. There is not much you can do about it but look for the HTTP response code (500 - Internal Server Error).
What you can do is to make your code more failsafe/devensive/robust so fatal errors don't appear. Do this by analysing your php error log which fatal errors appear and look inside the related code why they appear and how you can prevent these with correct error checking.
You can set up global error handling by using something like
$.ajaxSetup({
error:function(x,e){
if(x.status==0){
alert('You are offline!!\n Please Check Your Network.');
}else if(x.status==404){
alert('Requested URL not found.');
}else if(x.status==500){
alert('Internel Server Error.');
}else if(e=='parsererror'){
alert('Error.\nParsing JSON Request failed.');
}else if(e=='timeout'){
alert('Request Time out.');
}else {
alert('Unknow Error.\n'+x.responseText);
}
}
});
Or in the json response look at the error handler and decide what to do when it is passed with certain variables.
You don't want scripts to output error information in production environments, so you should disable error reporting there.
What kind of errors are you talking about? In your development environment, enable all errors and track them down, and program defensively to prevent errors from happening. There are many ways of doing this, depending on where the error comes from.
Finally, if you can trap errors, you could set some kind of error flag ($error = true), and on the final output, perform something like this:
echo '{"success": $error}';
if (!$error)
{
echo $the_requested_data;
}
You can then let jQuery read the success variable.
Depending on php configuration fatal errors will sometime (thanks PHP) result in an HTTP 200 response that will not be catched by jQuery as error but will be rather seen as a good response. So, as someone was already pointing, you should avoid having fatal errors (double checking error-prone parts of your code, catching exceptions, checking array indexes, declaring variables before using and so on).
i found my solution:
as i'm expecting a xml to be returned - i only need to check for the content-type of the response, when php raises an error i'm getting text/html instead of text/xml :)

How to Properly Catch a PHP error on Ajax call

I am retrieving javascript code from the server via the following ajax call
ajax (dojo):
dojo.xhrGet({
url : 'script.php',
handleAs : "javascript",
load : function(response){
/*Do Something*/
},
error : function(errorMessage) {
console.error(errorMessage);
}
});
script.php works fine, and, if the javascript code it returns is not valid code, the error handler will be invoked. However, the error message is incomplete, ie. it only shows the last function the error occurred in, not the entire chain of function calls. This is at times not very useful as I want to know where the error originated. Is there any way to output the entire trace?
Post the response of what you are returning.
I think you are better trying with a JSON response.
The reason I wasn't getting reliable error information is because I was using eval and I was expecting the same behavior I would observe having instead included those scripts. This question describes the differences and how eval runs the code whereas including those codes first inserts the code into the DOM then runs the code. The former is more efficient, but the latter is easier to debug.
I was getting the same error object on xhrPost for a _saveCustom, even though my response status was 200 (the 'handle:' is the same for GET and POST).
Actually handle: as 'json' will threw the error as well, but handle as 'text' worked and triggered the call to the load callback function.

How to trap PHP errors so they can be sent back in an AJAX response?

I'm using $.post for grabbing XML content from an external PHP script and I'm wondering - if that scripts raises a PHP error - how can I trap it in order to send it back inside my XML response?
I've tried implementing some PHP error trapping into that server-side-script like this:
$rc = set_error_handler("myErrorHandler");
Unfortunately it doesn't work. it still raises PHP errors the normal way.
Any ideas what could be wrong?
I generally check the response to the ajax request for error strings and then handle them on the Javascript side.

Has anyone ever successfully tracked down uncaught exception during ajax request?

How do ajax know whether it failed or succeeded if server side doesn't echo anything back?
$.ajax(error:..,success:..)
I met with this exception in my test:
uncaught exception: [Exception...
"Component returned failure code:
0x80040111 (NS_ERROR_NOT_AVAILABLE)
[nsIXMLHttpRequest.statusText]"
nsresult: "0x80040111
(NS_ERROR_NOT_AVAILABLE)" location:
"JS frame ::
http://localhost/script/tab.js ::
anonymous :: line 69" data: no]
The server side code is :
$id = process();
And for the purpose of testing,I have exit() in process();
Is that the reason for this exception?If so,why?
EDIT
I looked over to the line that cause exception,it's the error handling function of $.ajax()
error:function(XMLHttpRequest, textStatus, errorThrown){
alert(XMLHttpRequest.statusText);alert(textStatus);alert(errorThrown);
}
Anything wrong here?
The httprequest also returns a status such as 200 == ok, 404 == not found, 12152 == connection closed by server and so on..
Just read up on the status id's what they mean so you can look for them. you can also for debugging reasons just write out myhttprequest.status to the document and it shows what status it returned.
This depends on the status code the request returns. A successful request returns a status code in the range of 2xx, an error is in the range of 4xx of 5xx.
For more information see Wikipedia: List of HTTP status codes.
It would still get a response from the server, with the data part of it being empty. If it got no response at all, that would be an error.
http://docs.jquery.com/Ajax/jQuery.ajax#options
Give an option for success and error These functions will be called after the call is made.
There are four possible scenarios that you could get:
the server isn't there or refuses the connection (this is identifiable by the sockets library that the browser uses, which will report the connection failure)
the connection works and the server returns a non-success error code - this comes back in the header. Indeed, the request can succeed (200 code) even with an empty body, that's perfectly valid
the connection comes up but the server fails to respond - I'm not clear on the details of this, but i'd expect the JS to eventually time out because no response was received and return a failure based on that.
the connection comes up but the server responds incorrectly (e.g. no headers) - the JS implementation should return this as an error.
In any case, all the error scenarios are handled by the Javascript core's XMLHttpRequest implementation - jQuery just wraps it up with slightly tidier interface.
In your case (now you've provided more information) I would recommend that you use Firebug to see what the server response to your request is. That said, you shouldn't be getting an exception for anything inappropriate from the server, the JS should call the same error callback for all the above cases.
are you missing { } ?
$.ajax(error:..,success:..)
should be
$.ajax( { error: function( ){ } } );
if that's it, sorry dude, that would be annoying to have spent that much time on, haha
I fixed this by specifying a timeout in my ajax call. The ajax timeout was just giving up after X amount of time. Even though the page ended up returning data, the ajax object just gave up and bailed, but threw this error.

Categories