Search code examples
javascriptecmascript-6error-handlingpromisethrow

Does using catch require throw


Newbie question here - I have a program making API calls via promises/fetch. I want to add a catch, but I'm wondering do I need to also then have a throw statement in there? Or can I just use the catch alone?


Solution

  • I want to add a catch, but I'm wondering do I need to also then have a throw statement in there?

    No, you do not need a throw unless that's the programming result you want.

    A .catch() is used to "handle" a rejected promise. You, yourself, do not have to use a throw in order to handle a rejected promise.

    A throw might be used in conjunction with a .catch() if you want to execute some code when there's a rejected promise, but then return a rejected promise to the caller. In that case, you'd do something like this:

    function someFunction() {
        return fn().then(val => {
           // do something here when promise resolves
           return someVal;
        }).catch(err => {
           // do something here when promise rejects
           console.log(err);
           // throw the error to keep the returned promise rejected
           throw err;
        });
    }
    

    If you just have a .catch() without throwing inside it, then the rejected promise will be considered "handled" and will become resolved, not rejected. Note, this is pretty much the same as a try/catch works for synchronous code.

    Here's a perfectly fine example where you do not need a throw with the .catch().

    const rp = require('request-promise');
    const defaultConfig = {...};
    
    function readRemoteConfig(url) {
        return rp({url, json: true}).catch(err => {
            // when remote config is not available, substitute default config
            return defaultConfig;
        });
    }
    

    FYI, even if you want to keep the promise rejected, you don't have to use a throw to accomplish that. You can also return a rejected promise which will accomplish the same result:

    function someFunction() {
        return fn().then(val => {
           // do something here when promise resolves
           return someVal;
        }).catch(err => {
           // do something here when promise rejects
           console.log(err);
           // return rejected promise to keep the returned promise rejected
           return Promise.reject(err);
        });
    }
    

    It is a personal preference whether you want to do it this way or use throw.