Paul
Paul

Reputation: 1264

Chain jquery promises, but handle failures separately

The scenario is as following:

Out of this scenario, I want to create a function that returns a promise, which I can use like this from a client:

initData()
    .done(function(myArray) {
        processData(myArray);
    })
    .fail(function(response) {
        console.log("An error occured: " + response.errorMessage);
    });

The client should not care that initData() makes a call to a server, it should get the fail() called for both ajax call failures or server specific errors.

For this I need two things:

  1. Hide the failure of the server call and create a new error message object.
  2. Make the promise fail if the call to the server returned with an error message object.

Here's what I have:

function initData() {
    var promise = $.getJSON(url);

    return promise.then(function(response) {
        if (typeof response !== 'undefined' && response !== null && typeof response.errorMessage !== 'undefined') {
            // Do something to trigger fail() in the client caller.
        }
        return response;
    }, function(resp) {
        // This satisfies point 1 above.
        return { errorMessage: "Server error." };
    });
}

How may I satisfy the second requirement? I'm using jquery 3.1.1.

Thanks.

Upvotes: 1

Views: 451

Answers (2)

Brandon
Brandon

Reputation: 39192

Just throw an error from your then callback. The caller will "catch" it in their fail callback (though I suggest you learn to use standard then and catch and stop using jquery-specific done and fail).

function initData() {
    var promise = $.getJSON(url);

    return promise.then(function(response) {
        if (typeof response !== 'undefined' && response !== null && typeof response.errorMessage !== 'undefined') {
            throw new Error("uh oh!");
        }
        return response;
    }, function(resp) {
        // This satisfies point 1 above.
        throw new Error("server error");
    });
}

Upvotes: 1

Bergi
Bergi

Reputation: 664548

To fail the promise, simply throw the result instead of returning it:

function initData() {
    return $.getJSON(url)e.then(function(response) {
        if (typeof response !== 'undefined' && response !== null && typeof response.errorMessage !== 'undefined') {
            throw { errorMessage: "Response error." };
        }
        return response;
    }, function(resp) {
        throw { errorMessage: "Server error." };
    });
}

(This works only as of jQuery 3. For earlier versions, see Throwing an Error in jQuery's Deferred object)

Upvotes: 1

Related Questions