简体   繁体   中英

When do async methods throw and how do you catch them?

From node doc :

A handful of typically asynchronous methods in the Node.js API may still use the throw mechanism to raise exceptions that must be handled using try / catch. There is no comprehensive list of such methods; please refer to the documentation of each method to determine the appropriate error handling mechanism required.

Can someone bring example of such function which is async and still throws? How and when do you catch the exception then?

More particularly. Do they refer to such function:

try
{

   obj.someAsync("param", function(data){
                    console.log(data);
                 });
}catch(e)
{

}

Now normally I know above doesn't make sense -because when the callback executes, try block could have been already exited.

  • But what kind of example does the excerpt from documentation refer to? If async method throws as they say it, where, when and how should I handle it? (or maybe if you show such function can you show where in its doc it says how to handle it as mentioned on the quote?)

The async methods like the one from your example usually throw for programmer errors like bad parameters and they call the callback with error for operational errors.

But there are also async functions in ES2017 (declared with async function ) and those signal errors by rejecting the promise that they return - which turn into a thrown exception when you use them with await keyword.

Examples:

function x(arg, cb) {
    if (!arg) throw new Error('Programmer error: bad arguments');
    setTimeout(() => {
        cb(new Error('Operational error: something bad happened'));
    }, 2000);
}

Now when you use it you usually don't want to handle programmer errors - you want to fix them. So you don't do this:

try {
    x();
} catch (err) {
    // Why should I handle the case of bad invocation
    // instead of fixing it?
}

And the operational errors you handle like this:

x(function (err) {
    if (err) {
        // handle error
    } else {
        // success
    }
});

Now, if you have a function that doesn't take a callback but returns a promise:

function y() {
    return new Promise((res, rej) => setTimeout(() => rej('error'), 2000));
}

Then you handle the error like this:

y().catch(error => {
    // handle error
});

or, while using await :

try {
    await y();
} catch (err) {
    // handle error
}

For more info on the difference between operational errors and programmer errors see:

For more info on the promises and async / await see the links in this answer .

afaik there are three ways a async function could "throw"; and how to catch each of these:

  • as any other function (aka. someone messed up): I'd not catch these cases because they should not be in my code, and catching such errors makes it harder to find and fix em.

 function foo(){ //someone messed up, better fixing than catching this return new Prooooooooooomise((resolve) => 42); } try { foo(); }catch(err){ console.error(err); } 

  • Promises:

 function foo(){ return Promise.resolve('bar') } foo().then(value => value =========> 'error') .catch(err => { console.error(err); return "fixedValue"; }); 

  • And Nodes callback syntax/pattern:

 function foo(value, callback){ setTimeout(function(){ if(Math.random() < .5){ callback("I don't like to", undefined); }else{ callback(null, value * 2); } }, 500); } foo(21, function(err, data){ if(err){ //no try..catch at all console.error(err); }else{ //do whatever with data } }) 

These are the most common async errors you'll come along; well, the first one is just a plain bug in an async mothod.

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