简体   繁体   中英

Javascript uncaugh error in promise even with a catch

With Javascript, I am trying to make a call to an external API when a form is submited. I am using promises in order to set follow up actions once the call is done and to catch eventual errors.

This is where my problem is, even if I think I am catching my errors correctly, the console throws an

Uncaught (in promise) error: [The error I throw]

I do not understand why.

Here is a minimal version of my code which would reproduce the error when the refreshToken is expired:

try {
        functionGeneratingTheError();
    } catch (error) {
        doSomethingElse();
    }
function functionGeneratingTheError() {
    
    var getTokenCallPayload = {
        "client_id" : clientId,
        "client_secret" : clientSecret,
        "refresh_token" : refreshToken,
        "grant_type" : "refresh_token"
    };
    var getTokenCallOptions = {
        "method" : "POST",
        "body" : JSON.stringify(getTokenCallPayload),
        "muteHttpExceptions" : false
    };
    fetch(tokenURL, getTokenCallOptions)
    .then(response => {
        if (response.ok) {
            return response.json();
        } else {
            throw new Error("Error");
        }
    })
    .then(data => {
        doSomething();
    })  
    .then(response=> {
        doSomethingAgain();
    }) 
    .catch(error => {
        throw error;
    });
}

If I understand correctly, when the fetch is a bad request, it should throw the error "Error" which should then be caught in the first catch and run the doSomethingElse() function. However, instead of doing that, I get this error in the browser console "Uncaught (in promise) Error: Error"

What am I doing wrong?

I have tried including the fetch in a try{}catch(){} but it doesn't change anything.

I also tried not throwing the error and directly call my doSomethingElse() function, but then the following.then fails because data is undefined.

Change your functionGeneratingTheError function to return the chained promise like below:

function functionGeneratingTheError() {
    
    var getTokenCallPayload = {
        "client_id" : clientId,
        "client_secret" : clientSecret,
        "refresh_token" : refreshToken,
        "grant_type" : "refresh_token"
    };
    var getTokenCallOptions = {
        "method" : "POST",
        "body" : JSON.stringify(getTokenCallPayload),
        "muteHttpExceptions" : false
    };

    return
    fetch(tokenURL, getTokenCallOptions)
    .then(response => {
        if (response.ok) {
            return response.json();
        } else {
            throw new Error("Error");
        }
    })
    .then(data => {
        doSomething();
    })  
    .then(response=> {
        doSomethingAgain();
    }) 
    .catch(error => {
        throw error;
    });
}

And then await it in your calling code by wrapping the calling code inside an async self invoking function like so:

(async function() {
try {
        await functionGeneratingTheError();
    } catch (error) {
        doSomethingElse();
    }
})();

You can read more about async/await here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM