Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I catch an error from async without using await?

Can errors from a non-awaited async call be caught, sent to an original encapsulating try/catch, or raise an uncaught exception?

Here's an example of what I mean:

async function fn1() {     console.log('executing fn1'); }  async function fn2() {     console.log('executing fn2');     throw new Error('from fn2'); }  async function test() {     try {         await fn1();         fn2();     }     catch(e) {         console.log('caught error inside test:', e);     } }  test(); 

In this scenario, the error thrown from fn2 will be swallowed silently, and definitely not caught by the original try/catch. I believe this is expected behavior, since fn2 is most likely being shoved off to the event loop to finish at some point in the future, and test doesn't care when it finishes (which is intentional).

Is there any way to ensure that errors are not accidentally swallowed by a structure like this, short of putting a try/catch internal to fn2 and doing something like emitting an error? I would even settle for an uncaught error without knowing how to catch it, I think -- I don't expect thrown errors to be typical program flow with what I am writing, but swallowing errors makes it relatively annoying to debug.

Side note, I'm using Babel to transpile the code using the babel-runtime transform, and executing it with node.

like image 734
dvlsg Avatar asked Jun 04 '15 17:06

dvlsg


People also ask

Does async do anything without await?

In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. Code after each await expression can be thought of as existing in a .then callback.

Can we have a async function with and without await?

Async function without await insideWe can declare a function as async without using any await . In this case, the execution is not paused and your code will be executed in a non-blocking manner (asynchronous - no waiting). It is the same as not declaring that same function with async .

What can I use instead of async await?

There are a few alternative async/await transpilers to Regenerator, which take async code and attempt to convert to more traditional . then and . catch notation. In my experience, these transpilers work pretty well for simple functions, which await then return , perhaps with a try/catch block at most.


1 Answers

Dealing with unhandled rejected native promises (and async/await uses native promises) is a feature supported now in V8. It's used in the latest Chrome to output debugging information when a rejected promise is unhandled; try the following at the Babel REPL:

async function executor() {   console.log("execute"); }  async function doStuff() {   console.log("do stuff");   throw new Error("omg"); }  function handleException() {   console.error("Exception handled"); }  (async function() {   try {       await executor();       doStuff();   } catch(e) {       handleException();   } })() 

You see that, even though the exception from doStuff() is lost (because we're not using await when we call it), Chrome logs that a rejected promise was unhandled to the console:

Screenshot

This is also available in Node.js 4.0+, though it requires listening to a special unhandledRejection event:

process.on('unhandledRejection', function(reason, p) {     console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);     // application specific logging, throwing an error, or other logic here }); 
like image 172
Michelle Tilley Avatar answered Sep 26 '22 15:09

Michelle Tilley