I use async/await ecma6 standard without any custom library.
I don't get at the moment how I can properly catch and throw errors. I have multiple async/await functions and if somewhere down below an critical error happens I want to throw the error to the top and of all async functions and stop execution of the function.
I tried to throw exceptions out of the async/await function and catch it in the target function but I get a error in node.js:
this.basicAuthLogin= async function(user)
{
"use strict";
const login = new Login(this.host, this.url, user, user.pw);
//getSessionID throws error
this.sessionID = getSessionID(result.request.response);
}
(node:13964) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: getSessionID response is undefined (node:13964) [DEP0018] 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. Debugger attached.
So it seems I am not allowed to throw exceptions out of async functions or even rethrow it in the catch block of the promise in node.js?
So how do I get this working? Am I supposed to catch the error in the async function and return the error in the promise and rethrow then out of the async function?
this.basicAuthLogin= async function(user)
{
"use strict";
const login = new Login(this.host, this.url, user, user.pw);
try{
//getSessionID throws error
this.sessionID = getSessionID(result.request.response);
} catch(err) { return err;}
}
But this would mean that in my call stack from the first async function every function needs be async and I have to await the promise even though I don't really need it.
I hope somebody can enlighten me.
Regards Ruvi
Edit basic call stack pseudo code:
async startTest[arr]{
for (var i = 0; i < arr.length; i++)
{
try {
await runStep(arr[i];
} catch(err) {
console.log(err);
break;
}
}
}
async runStep(step)
{
try {
var userIsValid = await validateUser(step.user);
var req = buildRequest(step.request);
var result = await sendRequest(req);
var verify = verifyResult();
} catch(err){ throw err;}
}
async validateUser(user)
{
//make checks
//
var result = await this.authenticate(parameter).catch(err => {throw err});
userFound = true;
}
function authenticate(parameter) {
//can throw async function
basicAuthLogin(parameter).catch(err => {throw err};
}
function async basicAuthLogin(parameter()
{
try {
//can throw async function
var result = await request(parameter);
//can throw sync function
this.sessionID = getSessionID(response);
//can throw sync function
} catch(err) { throw err; }
}
One of the great things about
async
/await
is that they enabletry
/catch
to work with your asynchronous code.Your first
basicAuthLogin
function is absolutely fine (providedgetSessionID
is a synchronous function;if it isn't, you're missing an[you've now said it is]). The code usingawait
basicAuthLogin
must handle the possibility it will throw (either by handling the error or allowing it to propagate to its caller, which is responsible for handling it). So either:or
If the code using it does one of those two things (or lets the error propagate to code that does one of those two things), you won't get the "Unhandled rejection" error.
In response to my comment asking if
getSessionID
was asynchronous, you wrote:Here's a live example of doing that (in my case, I've made
basicAuthLogin
actually use something asynchronous prior togetSessionID
, but it doesn't really matter):The rule is just like it is with exceptions (because notionally these are exceptions):
Either handle it (e.g.,
try
/catch
), or let it propagate to the caller (typically by not doing anything at all), andThe top level MUST handle it
That Rule #2 means that when you transition from non-
async
code toasync
code (typically right at the top of your stack), you need a wrapper. Either:or
or of course:
The common denominator there is: The top level always handles the error.