4

An expected error is one from the server that I anticipated or even raised by myself in the code. For example, when a user attempts to perform an action for which he has no sufficient privilege, I would raise PermissionError (a custom Exception) with a message describing the error.

I have been searching for a good way to handle expected error for AJAX situation. The only requirement is to be able to display the error message to the user, as I want to keep my users in the loop of what's going on.

My current approach is packaging the error message into a JSON object and send it back to the client-end

var ajaxResponse = $.ajax({
    ....        
});

ajaxResponse.done(function(jsonObj) {
    if (jsonObj.success) {
        /* no error, do something */    
    }
    else {
        /* expected error returned, display jsonObj.error to user */
    }
});

ajaxResponse.fail(function(jqXHR, textStatus, errorThrown) {
    /* unexpected error returned */
});

I have another approach in mind, which I am not sure about. Basically, instead of packaging the message of expected error into a JSON object, in my django code I would return HttpResponse(content="no sufficient privilege", status=403). The client-end jQuery would get modified like the following:

ajaxResponse.done(function(response_data) {
    /* no error, do something */
});

ajaxResponse.fail(function(jqXHR, textStatus, errorThrown) {
    /* both expected and unexpected error would end up here.
     * It's an expected error when error code is 403 and 
     * jqXHR.responseText would give me the error message to 
     * display to the user.
     */
});

I like how the second approach groups all errors, expected or unexpected, in one place. But then, I have a feeling that http status code shouldn't be used this way. Anyways, I want to know which one is the right way to go. If neither, please share what you would do.

tamakisquare
  • 16,659
  • 26
  • 88
  • 129
  • "But then, I have a feeling that http status code shouldn't be used this way." Why not? It seems to me that indicating there was an error processing the request is **exactly** what status codes should be used for. – Anthony Grist Apr 20 '12 at 21:26
  • @AnthonyGrist - I share the same view as T.J. Crowder. Here is what he had to say in [another SO post](http://stackoverflow.com/a/6701385/338961). – tamakisquare Apr 20 '12 at 22:41

3 Answers3

3

Have a global configuration like this -

$.ajaxSetup({

     error: function(xhr){
         /* Do something with xhr.responseText */
         window.status='Your error message goes here';
     }

});
Robin Maben
  • 22,194
  • 16
  • 64
  • 99
  • that's not the answer I am looking for. It's not my concern on how and/or where to display the error message. I am looking for a structured and consistent way to handle expected server errors to displaying them to user. – tamakisquare Apr 20 '12 at 22:53
  • @ahmoo: The how is just my preference. The "structure" is in setting up error handling in one place across your application. Hence, the use of `ajaxSetup()`. – Robin Maben Apr 21 '12 at 12:34
1

The jqXHR object contains all the information about the failed response. First allow me to simplify the way you do a request:

 $.ajax({
        url: '/the/posting/url',
        type: 'POST',
        data: { param: value, param_two: value_two},
        success: function(){
            alert('Everything went as is supposed to be.');
        },
        error: function(jqXHR, t, e){
            console.log(jqXHR.responseText);
        }
    })

So, this way you manage what you want to do if the request is good or not. Then you see I wrote something like:

console.log(jqXHR.responseText);

That's because that property tells you the error detailed (depending on how you put the trace when something goes wrong). You can read it in the console of Firebug (Firefox) or Developer Tools (Chrome and Safari).

There's no need to serialize an object to json to know something went wrong, because django (I supposed) sends the error as is, and error. So when jquery knows something was just wrong, it will trigger the error property for the ajax object and that's it, and you can read in the console.

Omar
  • 689
  • 3
  • 16
  • 3
    FYI. Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks will be deprecated in jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead. – tamakisquare Apr 20 '12 at 21:49
0

I personally always use approach one, especially since there are more error conditions than http error codes. Also there might be cases where your js code isn't able to distinguish between expected and unexpected errors if you use the second approach.

  • I think I can use status code 403 to distinguish between expected and unexpected errors. Don't think 403 response would ever get sent unless I intentionally trigger it. – tamakisquare Apr 20 '12 at 22:49