How to Handle Errors in jQuery $.ajax() Requests

Handling errors in a jQuery $.ajax() request is essential for building resilient web applications that gracefully inform users when network requests fail, servers return errors, or data parsing issues occur. This guide covers the primary methods for catching and managing AJAX failures, including the modern .fail() promise callback, the built-in error configuration property, the status-code-specific statusCode map, and global listeners for application-wide error handling.

jQuery's $.ajax() returns a jqXHR object, which implements the Promise interface. The standard and most flexible way to capture errors is by chaining the .fail() method to the request:

$.ajax({
    url: "https://api.example.com/data",
    type: "GET",
    dataType: "json"
})
.done(function(data) {
    console.log("Success:", data);
})
.fail(function(jqXHR, textStatus, errorThrown) {
    console.error("Request failed: " + textStatus);
    console.error("Error details: " + errorThrown);
    console.error("HTTP Status: " + jqXHR.status);
});

Understanding the Callback Parameters

The error callback receives three arguments:

  • jqXHR: The jQuery XMLHttpRequest object. It provides response properties such as jqXHR.status (HTTP status code like 404 or 500) and jqXHR.responseText (the raw response body sent by the server).
  • textStatus: A string categorizing the error. Common values include "timeout", "error", "abort", and "parsererror".
  • errorThrown: The textual portion of the HTTP status, such as "Not Found" or "Internal Server Error".

2. Using the error Option in Settings

You can also define an error function directly within the configuration object passed to $.ajax(). This is functionally equivalent to .fail():

$.ajax({
    url: "https://api.example.com/data",
    method: "POST",
    data: { name: "John" },
    success: function(response) {
        console.log("Success:", response);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        if (textStatus === "parsererror") {
            alert("Error parsing JSON response.");
        } else {
            alert("Request failed: " + errorThrown);
        }
    }
});

3. Handling Specific HTTP Status Codes with statusCode

If your application needs custom logic depending on the exact HTTP status returned by the server (such as redirecting on 401 Unauthorized or displaying an alert on 404 Not Found), use the statusCode property:

$.ajax({
    url: "https://api.example.com/profile",
    statusCode: {
        401: function() {
            alert("Session expired. Please log in again.");
            window.location.href = "/login";
        },
        404: function() {
            alert("The requested resource was not found.");
        },
        500: function() {
            alert("Internal server error. Please try again later.");
        }
    }
});

When a status code matches an entry in the map, its corresponding function runs in addition to any general .fail() or error callbacks.

4. Catching JSON Parsing Errors (parsererror)

A common issue occurs when the server returns an HTTP 200 OK status, but the response body is not valid JSON (e.g., an HTML error page or empty response). In this scenario, jQuery routes the response to the error handler instead of the success handler with textStatus set to "parsererror".

To handle this, inspect textStatus:

.fail(function(jqXHR, textStatus, errorThrown) {
    if (textStatus === "parsererror") {
        console.error("Malformed JSON received from server:", jqXHR.responseText);
    }
});

5. Setting Up Global AJAX Error Handling

To avoid duplicating error-handling code across multiple requests, you can bind a global error handler using $(document).ajaxError(). This function executes whenever any $.ajax() call on the page fails:

$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
    console.error("Global Error Handler:");
    console.error("URL:", ajaxSettings.url);
    console.error("Status:", jqXHR.status);
    console.error("Message:", thrownError);

    // Display a global user-facing notification
    $("#notification-bar").text("A network error occurred. Please check your connection.").show();
});

If you have a specific request that should not trigger the global error handler, set global: false in that request's options:

$.ajax({
    url: "https://api.example.com/background-sync",
    global: false
});