There are some peculiarities related to the use of the try/catch construct when it comes to the async/await model.
This construct is used to handle exceptions. The code within the try
block is evaluated and if it raise an exception, the JavaScript interpreter passes the control to the catch
block where you can inspect the error's details contained in an error object.
try {
let result = 5 / 0;
} catch(err) {
console.log(err);
}
Since Promises usually return a custom error object when they are rejected, catch
will show you the details of the rejection error.
'use strict';
const isEven = num => {
return new Promise((resolve, reject) => {
if(typeof num !== 'number') {
reject({error: 'Not A Number'});
}
if( num % 2 === 0 ) {
resolve(true);
} else {
reject({error: 'Odd Number'});
}
});
};
const test = async () => {
try {
let result = await isEven(Math.floor(Math.random() * 10));
console.log(result);
} catch(err) {
console.log(err);
}
};
In this case our Promise will return a truthy value in case of an even number and a custom error object either when the number is odd or is not a number. The catch
block will simply handle the Promise's rejection.
Things get more complicated when in the try
block we raise an unexpected error which is not related to Promises:
const test = async () => {
try {
let result = await isEven(2);
let x = 5 / 0;
} catch(err) {
console.log(err);
}
};
Here the error object will be an empty object ({}
) with no details about the exception raised in the try
block. It becomes extremely difficult to track down such errors because our first thought is that there's a problem with Promises.
However, this is not the case, because Promises are normally designed to be very detailed when it comes to describing the condition that led to their rejection.