Last updated: Mar 7, 2024
Reading timeยท7 min
The error "UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch()" occurs for multiple reasons:
async
function without a catch
block..catch()
.catch()
function.node:internal/process/promises:289 triggerUncaughtException(err, true /* fromPromise */); ^ [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "An error occurred".] { code: 'ERR_UNHANDLED_REJECTION' }
Here is an example of how the error occurs.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); // โ๏ธ [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "An error occurred".] {code: 'ERR_UNHANDLED_REJECTION'} p.then((data) => { console.log('.then block ran: ', data); });
.then()
function but doesn't have a .catch()
function.We can add a .catch()
function to handle the error.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); p.then((data) => { console.log('.then block ran: ', data); }).catch(err => { // ๐๏ธ .catch block ran: An error occurred console.log('.catch block ran: ', err); });
The .catch()
function got called with the error and handled the rejected
Promise.
We called the then() function on the promise object to resolve the promise.
then()
method gets called with the resolved value as a parameter. We can access this value in the body of the method.Notice that we also used the catch() method.
This is necessary because a promise can have 3 states:
pending
- initial state, neither fulfilled nor rejected.fulfilled
- the operation was successful and the promise is resolved.rejected
- operation failed.then
method will get called if the promise is fulfilled and the operation is successful.If the promise is rejected, we can access the reason (error) for the rejection
in the catch()
method.
Here is an example of using the resolve()
function to resolve the Promise and
run the then() function instead.
const p = new Promise((resolve, reject) => { return resolve('Success message'); }); p.then(data => { // ๐๏ธ .then block ran: Success message console.log('.then block ran: ', data); }).catch(err => { console.log('.catch block ran: ', err); });
We called the resolve()
function, so the .then()
function got called with
the resolved value as a parameter.
async
functions without a try/catch
statementAnother common cause of the error is having a rejected promise in an async
function without a catch
block.
Here is an example.
async function doWork() { const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); const data = await p; console.log('data is: ', data); } // โ๏ธ [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "An error occurred".] {code: 'ERR_UNHANDLED_REJECTION'} doWork();
async
function in which a Promise is rejected, but there is no try/catch
statement to handle the rejected promise.To solve the error, we have to wrap the await
statement in a try
block, so
if an error is raised, it gets passed to the catch()
function.
async function doWork() { const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); try { const data = await p; console.log('data is: ', data); } catch (err) { // ๐๏ธ catch block ran: An error occurred console.log('catch block ran: ', err); } } doWork();
We await the Promise in the try
block but it gets rejected, so the catch()
function is called.
The catch
function gets passed the error (rejection reason) and handles the
error.
This way we don't get an unhandled promise rejection error.
The result of awaiting the promise is the resolved value if the operation was successful.
The await operator is used to wait for a Promise to be fulfilled or rejected.
await
operator is used, our code in the particular function stops on the line where await
was used until the promise was fulfilled or rejected.Here is an example of using the resolve()
function to demonstrate the success
case.
async function doWork() { const p = new Promise((resolve, reject) => { return resolve('Success message'); }); try { const data = await p; // ๐๏ธ data is: Success message console.log('data is: ', data); } catch (err) { console.log('catch block ran: ', err); } } doWork();
We await the Promise, it gets resolved with the string 'Success message' and
the string gets assigned to the data
variable.
Using the async/await
syntax makes your code more predictable and easier to
read than using .then()
and .catch()
.
.catch()
functionIf you raise an error in your .catch()
function without handling it, the
Unhandled Promise Rejection error occurs.
Here is an example.
async function doWork() { const p = new Promise((resolve, reject) => { return reject('First error'); }); try { const data = await p; console.log('data is: ', data); } catch (err) { console.log('catch block ran: ', err); // ๐๏ธ this raises an error throw new Error('An error occurred in catch'); } } // โ๏ธ catch block ran: First error // โ๏ธ Error: An error occurred in catch doWork();
We await the Promise in the try
block and it gets rejected.
catch()
function gets called with the error and handles it, but then it raises another error that isn't handled.The second error is the reason for the Unhandled Promise Rejection error.
There is no code in our application that handles the second error that occurred
in our catch()
function.
Make sure you don't have any code that might raise an error in your catch()
functions.
IIFE (immediately invoked function expressions) can be used to wrap a promise without it being connected to other code in any way, e.g. configuration or database connection initialization code.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); (async function () { try { const data = await p; console.log(data); } catch (err) { // ๐๏ธ Catch block ran: An error occurred console.log('Catch block ran: ', err); } })();
We wrapped an async
function in an immediately invoked function expression.
The promise that we awaited got rejected, so the rejection reason got passed to
the catch()
function.
Had we just awaited the promise without a catch()
function, we would have
gotten the error.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); // โ๏ธ [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "An error occurred".] {code: 'ERR_UNHANDLED_REJECTION'} (async function () { const data = await p; console.log(data); })();
.catch()
function is connected to your .then()
functionHere is another example of how the error occurs.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); p.then(data => { console.log('data is: ', data); }); // โ๏ธ [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "An error occurred".] { code: 'ERR_UNHANDLED_REJECTION' } p.catch(err => { console.log('err is: ', err); });
We have a .catch()
function but it isn't connected to the .then()
function
call.
To solve the error, we have to chain the .catch()
call after the .then()
call.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); p.then(data => { console.log('data is: ', data); }).catch(err => { // ๐๏ธ err is: An error occurred console.log('err is: ', err); });
You might also see examples online that use the second parameter of the
.then()
function instead of using .catch()
.
const p = new Promise((resolve, reject) => { return reject('An error occurred'); }); p.then( data => { console.log('data is: ', data); }, err => { // ๐๏ธ err is: An error occurred console.log('err is: ', err); }, );
The code sample is similar to using .then()
and .catch()
.
You can imagine that the second function we passed to .then()
gets treated
like a .catch()
function and gets called with the rejection reason.
However, you should generally stick to using .catch()
because it is more
readable and intuitive.
To solve the error "UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()", make sure:
async
function without a catch
block..catch()
.catch()
function.You can learn more about the related topics by checking out the following tutorials: