Await in Catch Block

try/catch blocks with async/await

Alternatives

An alternative to this:

async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}

would be something like this, using promises explicitly:

function main() {
getQuote().then((quote) => {
console.log(quote);
}).catch((error) => {
console.error(error);
});
}

or something like this, using continuation passing style:

function main() {
getQuote((error, quote) => {
if (error) {
console.error(error);
} else {
console.log(quote);
}
});
}

Original example

What your original code does is suspend the execution and wait for the promise returned by getQuote() to settle. It then continues the execution and writes the returned value to var quote and then prints it if the promise was resolved, or throws an exception and runs the catch block that prints the error if the promise was rejected.

You can do the same thing using the Promise API directly like in the second example.

Performance

Now, for the performance. Let's test it!

I just wrote this code - f1() gives 1 as a return value, f2() throws 1 as an exception:

function f1() {
return 1;
}

function f2() {
throw 1;
}

Now let's call the same code million times, first with f1():

var sum = 0;
for (var i = 0; i < 1e6; i++) {
try {
sum += f1();
} catch (e) {
sum += e;
}
}
console.log(sum);

And then let's change f1() to f2():

var sum = 0;
for (var i = 0; i < 1e6; i++) {
try {
sum += f2();
} catch (e) {
sum += e;
}
}
console.log(sum);

This is the result I got for f1:

$ time node throw-test.js 
1000000

real 0m0.073s
user 0m0.070s
sys 0m0.004s

This is what I got for f2:

$ time node throw-test.js 
1000000

real 0m0.632s
user 0m0.629s
sys 0m0.004s

It seems that you can do something like 2 million throws a second in one single-threaded process. If you're doing more than that then you may need to worry about it.

Summary

I wouldn't worry about things like that in Node. If things like that get used a lot then it will get optimized eventually by the V8 or SpiderMonkey or Chakra teams and everyone will follow - it's not like it's not optimized as a principle, it's just not a problem.

Even if it isn't optimized then I'd still argue that if you're maxing out your CPU in Node then you should probably write your number crunching in C - that's what the native addons are for, among other things. Or maybe things like node.native would be better suited for the job than Node.js.

I'm wondering what would be a use case that needs throwing so many exceptions. Usually throwing an exception instead of returning a value is, well, an exception.

Node js await for an async call made in catch block throwing error

According to definition: await can be used only in async functions.

So your nested function has to async be as well

async function begin() {
await shouldFail().then( message =>
console.log(message)
).catch( async () => { // here -----------------
await shouldFail().then( message =>
console.log(message)
).catch( message =>
console.log(message)
)
})
}

Why is try {} .. catch() not working with async/await function?

You need to await errorTest

const callFunction=async()=>{
try{
const result = await errorTest()
}catch(err){
console.log(err)
}
}
callFunction ()

Note that the await errorTest() function has to also be in an async function. That's why I put it inside callFunction ()

Another Option

const errorTest = async() => { 
try{
const result = await $.get("http://dataa.fixer.io/api/latest?access_key=9790286e305d82fbde77cc1948cf847c&format=1");

console.log(result)
}catch(err){
console.log(err)
}
}

NodeJS: Await Skips Catch Block and Exits Function. Why?

await does not block. It suspends execution of the local function and that function, then immediately returns a promise. The caller needs to use that promise to know when the operation is done. You are actually calling process.exit() before your file read has finished. What is happening here is this:

  1. Your code executes await readFile(fileName, 'utf-8'); and the uploadFile() function is suspended and immediately returns a promise.
  2. console.log("Done") runs
  3. process.exit(0) runs.
  4. The file has not yet been read yet and your program has exited.

Instead, you can do something like this:

async function Main() {
const fileName = './Diagnostics_Data_Analysis/AddingToDynamoDB/diag.txt';
const c = await uploadFile(fileName);
console.log("Done");
process.exit(0);
}

This will wait for the uploadFile() function to actually notify completion before calling process.exit(0).

P.S. Nodejs now has promise versions of the fs library built in already, so you can use fs.promises.readFile() and don't have to make your own promisified version of that.

A good solution for await in try/catch/finally?

You can move the logic outside of the catch block and rethrow the exception after, if needed, by using ExceptionDispatchInfo.

static async Task f()
{
ExceptionDispatchInfo capturedException = null;
try
{
await TaskThatFails();
}
catch (MyException ex)
{
capturedException = ExceptionDispatchInfo.Capture(ex);
}

if (capturedException != null)
{
await ExceptionHandler();

capturedException.Throw();
}
}

This way, when the caller inspects the exception's StackTrace property, it still records where inside TaskThatFails it was thrown.



Related Topics



Leave a reply



Submit