Clean way to throw php exception through jquery/ajax and json
As a complement to the previous answers, instead of repeating the same code for json encoding in all your exceptions, you could set an exception handler to be used only in the needed scripts. For instance:
function ajaxExceptionHandler($e) {
echo json_encode(array(
'error' => array(
'code' => $e->getCode(),
'msg' => $e->getMessage())
));
}
Then, in your ajax handler,
set_exception_handler('ajaxExceptionHandler');
If all the errors should be treated in the same way (showing a dialog for example). You can do it this way:
PHP End:
public function throwJsonException($msg) {
echo json_encode(array('error'=> true, 'msg' => $msg));
}
throwJsonException('login invalid!');
jQuery End:
$(document).ajaxSuccess(function(evt, request, settings){
var data=request.responseText;
if (data.length>0) {
var resp=$.parseJSON(data);
if (resp.error)
{
showDialog(resp.msg);
return;
}
}
});
Facebook do something in their PHP SDK where they throw an exception if a HTTP request failed for whatever reason. You could take this approach, and just return the error and exception details if an exception is thrown:
<?php
header('Content-Type: application/json');
try {
// something; result successful
echo json_encode(array(
'results' => $results
));
}
catch (Exception $e) {
echo json_encode(array(
'error' => array(
'code' => $e->getCode(),
'message' => $e->getMessage()
)
));
}
You can then just listen for the error
key in your AJAX calls in JavaScript:
<script>
$.getJSON('http://example.com/some_endpoint.php', function(response) {
if (response.error) {
// an error occurred
}
else {
$.each(response.results, function(i, result) {
// do something with each result
});
}
});
</script>
You could do something like this in PHP (assuming this gets called via AJAX):
<?php
try {
if (some_bad_condition) {
throw new Exception('Test error', 123);
}
echo json_encode(array(
'result' => 'vanilla!',
));
} catch (Exception $e) {
echo json_encode(array(
'error' => array(
'msg' => $e->getMessage(),
'code' => $e->getCode(),
),
));
}
In JavaScript:
$.ajax({
// ...
success: function(data) {
if (data.error) {
// handle the error
throw data.error.msg;
}
alert(data.result);
}
});
You can also trigger the error:
handler of $.ajax() by returning a 400 (for example) header:
header('HTTP/1.0 400 Bad error');
Or use Status:
if you're on FastCGI. Note that the error:
handler doesn't receive the error details; to accomplish that you have to override how $.ajax()
works :)