29

Let's say I have the following jQuery AJAX call:

$.ajax({
   type: "POST",
   url: "MyUrl",
   data: "val1=test",
   success: function(result){
        // Do stuff
   }
 });

Now, when this AJAX call is made I want the server-side code to run through a few error handling checks (e.g. is the user still logged in, do they have permission to use this call, is the data valid, etc). If an error is detected, how do I bubble that error message back up to the client side?

My initial thought would be to return a JSON object with two fields: error and errorMessage. These fields would then be checked in the jQuery AJAX call:

$.ajax({
   type: "POST",
   url: "MyUrl",
   data: "val1=test",
   success: function(result){
       if (result.error == "true") 
       {
           alert("An error occurred: " & result.errorMessage);
       }
       else 
       {
           // Do stuff
       }
   }
 });

This feels a bit clunky to me, but it works. Is there a better alternative?

Kevin Pang
  • 41,172
  • 38
  • 121
  • 173

5 Answers5

31

Personally, I have similar code to the following code in my library.

$.ajaxSetup({
    error: function(xhr){
        alert('Request Status: ' + xhr.status + ' Status Text: ' + xhr.statusText + ' ' + xhr.responseText);
    }
});

jQuery docs Ajax/jQuery.ajaxSetup

The best way to bubble that error from the server side (using php) to the client side is to send a header through the Ajax request somewhere in the 400's (which is always associated with errors). Once the Ajax request receives this it will trigger your error function. This also means that you do not have to define an error: call in every $.ajax call.

header('HTTP/1.0 419 Custom Error');

Quote from w3.org header information

Error 4xx, 5xx The 4xx codes are intended for cases in which the client seems to have erred, and the 5xx codes for the cases in which the server is aware that the server has erred. It is impossible to distinguish these cases in general, so the difference is only informational. The body section may contain a document describing the error in human readable form. The document is in MIME format, and may only be in text/plain, text/html or one for the formats specified as acceptable in the request.

Asciant
  • 2,130
  • 1
  • 15
  • 26
  • From the jQuery documentation: "This can cause undesirable behavior since other callers (for example, plugins) may be expecting the normal default settings. For that reason we _strongly recommend against using this API_" https://api.jquery.com/jQuery.ajaxSetup/ – Colin Aug 13 '21 at 09:16
8
$.ajax({
   type: "POST",
   url: "MyUrl",
   data: "val1=test",
   success: function(result){
        // Do stuff
   },
   error: function(request,status,errorThrown) {
        // There's been an error, do something with it!
        // Only use status and errorThrown.
        // Chances are request will not have anything in it.
   }
 });
Salty
  • 6,688
  • 3
  • 33
  • 31
  • 2
    For me, status is always "error" and errorThrown is always undefined. How do you get any interesting info out of here? – Remi Despres-Smyth Apr 19 '10 at 19:25
  • Really, the OP had the right idea. If your 200 response/result is going to contain an error message, the only way to alert it is in the success function. Sometimes you'll have to do `msg = JSON.parse(response)` before the `if (msg.errors) { do an alert }` bit, then `else { \\do the thing }`. Even trying it the other way around (handle msg.success first) seemed to give me difficulties (the alert would not pop up until the user clicked something else on the page). – eon May 01 '18 at 20:35
3

Doesn't the jQuery ajax function accept one more parameter at the end, a callback for failed calls? If so, just add a fail:function(...){..} after the success callback.

rodbv
  • 5,214
  • 4
  • 31
  • 31
  • Yes, there is an "error" callback that works the same way the "success" callback does. However, I wasn't sure if returning an HTTP error was the best approach here. – Kevin Pang Jan 02 '09 at 18:27
  • As long as you take care of the error on the server side (logging, etc), there's no problem on sending it to the client, so it can handle as well. – rodbv Jan 02 '09 at 19:39
0

It's pretty late to answer this question but I think It will be beneficial to some one using es6 and jquery 2.2.

I generally follow this (deferred approach) in my code

sendAjaxRequest(URL, dataToSend) {
    return $.ajax({
        type        : 'POST',
        url         : URL,
        data        : JSON.stringify(dataToSend),
        dataType    : 'json'
    }).fail((responseData) => {
        if (responseData.responseCode) {
            console.error(responseData.responseCode);
        }
    });
},

I have attached a deferred fail method which will be called if some error occurs. It is an alternative construct to the error callback option, the .fail() method replaces the deprecated .error() method in latest jquery.

Next from the place of calling sendAjaxRequest I use then jquery promise callback

sendAjaxRequest(URL, dataToSend)
.then(
     (success) => {
     },
     (error) => {
     }
);

It will call success or error function based on the response received from server.

WitVault
  • 23,445
  • 19
  • 103
  • 133
0

Return an error code on the server side using the HTTP error the best equates to what the error is. Then use the error callback. This will also allow you to show errors given by your webserver.

Adam Peck
  • 6,930
  • 3
  • 23
  • 27