I have an async function that I expect to throw exception on failure. However something seems to preventing this:
by omitting the try catch blocks I expect an exception to be thrown which I want to handle outside of the function.
The actual result I get is somewhat confusing:
(node:10636) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): E11000 duplicate key error index.
(node:10636) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
async f(obj) { await db.collection('...').save(obj); }
I get the same result when I try to catch the exception and throw something else instead:
async f(obj) { try { await db.collection('...').save(obj); } catch(e) { throw e.message; } }
The function is called from a try block, so don't see how this is an Unhandled Promise.
I am trying to use f
as a parameter of another function:
g(obj, handler) { try { handler(obj); } catch(e); ... } } g(objToSave, f);
Implement try-catch within the function This is the solution to catch exceptions in asynchronous methods. Have a look at the following code. If you look closely inside the ShowAsync() function, then you will find we have implemented a try-catch within Task. run().
When an exception occurs in an async method that has a return type of Task or Task, the exception object is wrapped in an instance of AggregateException and attached to the Task object. If multiple exceptions are thrown, all of them are stored in the Task object.
async f(obj) { try { await db.collection('...').save(obj); } catch(e) { throw e.message; } }
The function is called from a try block, so don't see how this is an Unhandled Promise.
What is unhandled here is the rejection of a promise returned by the f()
function, not by the .save()
method. So this will not cause that problem:
async f(obj) { try { await db.collection('...').save(obj); } catch(e) { console.error(e.message); } }
Throwing an exception in async function always rejects the promise that is returned by that function.
To catch the exception you either have to do this in another async function:
try { asyncFunc(); } catch (err) { // you have the error here }
or you can add a rejection handler explicitly:
asyncFunc().catch(err => { // you have the error here });
If you are catching the exception and throwing another exception then you get the same problem, just in a different function.
You either have to add a promise rejection handler and not throw an exception or return a rejected promise there - or run that function in another async function that handles the exception instead of rethrowing the same or new exception.
To sum it up: Every async
function returns a promise. Every promise needs to have a rejection handler.
The rejection handler is added using a two-function .then()
or with .catch()
, or with try { await asyncFunction(); } catch (err) { ... }
When you have a promise rejection with no rejection handler, you will get a warning in older versions of Node and a fatal error in newer versions of Node - see this answer for more details:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With