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:
- Your code executes
await readFile(fileName, 'utf-8');
and theuploadFile()
function is suspended and immediately returns a promise. console.log("Done")
runsprocess.exit(0)
runs.- 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
Using Webclient or Webrequest to Login to a Website and Access Data
How to Add the Same Column to All Entities in Ef Core
Reading a Binary File and Using Response.Binarywrite()
Gracefully Handling Corrupted State Exceptions
Setting Dropdownlist Selecteditem Programmatically
Why Does Guid.Tobytearray() Order the Bytes the Way It Does
Why Is List When Passed Without Ref to a Function Acting Like Passed with Ref
C# Linq Intersect/Except with One Part of Object
ASP.NET Button Onclick Event Not Firing
How to Convert String to Integer in C#
Mongodb .Net Driver 2.0 Pull (Remove Element)
How to Disable Cascade Delete for Link Tables in Ef Code-First
Save Modified Wordprocessingdocument to New File
How to Export a Gridview.Datasource to a Datatable or Dataset
Error: Must Create Dependencysource on Same Thread as the Dependencyobject Even by Using Dispatcher