Handling errors raised by jQuery Ajax method

seadrag0n picture seadrag0n · Apr 18, 2013 · Viewed 9.3k times · Source

I have a page in which I am using a jQuery ajax method to call a simple Webservice which will get some data from the database and bind it to some controls in the page. The ajax method is called on the onchange event of select (here the HTTP request is POST). Following is the jQuery ajax method

function CallAjax(url, jsonData, SucessFunction, FailurFunction) {
$.ajax({
    type: "POST",
    url: url,
    data: jsonData,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: SucessFunction,
    error: function(){
       alert('error occured');
    }
});

}

The URL for above method is somepage.aspx/getDataFromDatabse where getDataFromDatabse is the webservice method. Our testers are testing the page using burp suite. When they are directly tying to access the url(www.example.com/somepage.aspx/getDataFromDatabse) in the browser, the HTTP method shown in burp suite is GET and an error is raised and the user is getting redirected to the appropriate page. But when they are directly accessing the above URL and intercepting the request in burp suite and changing GET request to POST request the following error message is displayed directly in the browser:

{"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""}

The "error" in the above ajax function is not getting executed and the alert box is not shown and we are able to handle the error. How to handle such an error and redirect the user to a custom page?

Answer

Chris picture Chris · Apr 18, 2013

It would appear that the response from your server is a valid JSon response, despite the fact that it contains what (to you) reads as an error. As such the $.ajax(...) call is handling the response as a success, not an error.

You can return a valid JSon response and within that response indicate whether there was an error or not, along with any additional info such as a user-friendly error message, a redirect URL, etc.

The error: handler of the $.ajax(...) call should be used for real server response errors (i.e. unhandled 500 errors, timeouts etc.)

For example, your successful JSon response could be something like:

{
    success: true,
    errorMessage: null,
    errorRedirectUrl: null,
    data: { .... your successful data response .... }
}

and your failed JSon response (e.g. due to validation problems, not server failures) would look like this:

{
    success: false,
    errorMessage: 'There was an error processing the request.',
    errorRedirectUrl: 'http://....someurl...',
    data: null
}

Then you check for response.success == true in the success: option of the $.ajax(....) call, and handle appropriately.

By having a single, consistent structure the success: option handles all ajax requests which complete and then determines whether there was a handled error and what to do with it, such as display an alert to the user, redirect them to a URL, etc...

In contrast, the error: option handles only those ajax requests which didn't come back with a response you can use.

Update:

On your server you are already handling the difference between receiving a GET http request and a POST http request. So, I think your problem is that you also need to detect whether the POST request contains valid data in the format the webservice method needs.

So, your web service needs to decide if the POSTed data in the http request is in a format it expects to receive and if not return an HTTP redirect response (302) rather than returning the error.

You could do this in 2 ways:

  1. Using a Try... Catch... block. Your webservice method already appears to be throwing an exception and returning it, so catch it and then instead of returning it, set up and return a 302 response instead.

  2. If genuine calls to the webservice can generate exceptions under normal operations (this is usually bad!) you'll need to validate the data received in the request to see if it is what the webservice method expects to receive (was data received? was it the right structure as would be sent by the ajax request? etc.)

Note: if the request does contain valid data then there is no easy way to detect whether this came from a genuine source (the ajax call) or a forged request by some other means. There are solutions to this, but they are involved and can require multiple calls for authentication etc.