Skip to main content

How to Solve the "UnhandledPromiseRejection" Error in JavaScript

The UnhandledPromiseRejection error is a critical warning in modern JavaScript that occurs when a Promise is rejected, but there is no code in place to handle that rejection. This is the asynchronous equivalent of an uncaught Exception in synchronous code.

This guide will explain what an unhandled rejection is and show you the correct ways to solve it using both the classic .catch() method and the modern async/await with try...catch blocks.

The Core Problem: What is an Unhandled Promise Rejection?

A Promise has two potential outcomes: it can be fulfilled (succeed) with a value, or it can be rejected (fail) with a reason (usually an Error object).

An "unhandled rejection" happens when a promise is rejected, but you have not provided any code to "catch" and deal with that failure. Modern JavaScript runtimes (like Node.js and browsers) will detect this and issue a warning or even terminate the process, because it's a sign of a potential bug in your code.

Example of problem:

// This Promise is immediately rejected.
const myPromise = Promise.reject(new Error('Something went wrong!'));

// We only handle the success case with .then(), but not the failure case.
myPromise.then(result => {
console.log('This will never run.');
});

// ⛔️ UnhandledPromiseRejectionWarning: Error: Something went wrong!

Solution for .then() syntax: Chaining a .catch() Block

If you are using the .then() syntax to handle a Promise, you must also chain a .catch() block to handle any potential rejections.

const myPromise = Promise.reject(new Error('Something went wrong!'));

myPromise
.then(result => {
// This part handles the success case.
console.log('Success:', result);
})
.catch(error => {
// ✅ Correct: This block "catches" the rejection and handles the error.
console.error('Caught an error:', error.message);
});

// # Output: Caught an error: Something went wrong!
note

By adding the .catch() block, you are telling the JavaScript engine, "I have a plan for what to do if this fails," and the unhandled rejection warning is resolved.

The async/await syntax is the modern and most readable way to work with promises. When you await a promise, any rejection is transformed into a standard, synchronous-style throw. To handle this, you must wrap your await calls in a try...catch block.

Example or problem:

async function fetchData() {
// This function will throw an error when `myPromise` rejects.
const result = await Promise.reject(new Error('Something went wrong!'));
return result;
}

// ⛔️ UnhandledPromiseRejectionWarning: The error thrown inside fetchData is not caught.
fetchData();

Solution: wrap the potentially failing code inside a try block and handle the error in the catch block.

async function fetchData() {
try {
// ✅ Correct: The await call is inside a `try` block.
const result = await Promise.reject(new Error('Something went wrong!'));
return result;
} catch (error) {
// This block runs if the awaited promise is rejected.
console.error('Caught an error:', error.message);
}
}

fetchData();
// # Output: Caught an error: Something went wrong!
note

This is the recommended best practice for handling errors in modern asynchronous code.

A Common Pitfall: Throwing an Error from a .catch() Block

It's important to remember that if you throw a new error from inside a .catch() block, that new error must also be handled somewhere.

Example of problem:

async function doSomething() {
try {
await Promise.reject(new Error('Initial error'));
} catch (error) {
console.error('Caught the initial error:', error.message);

// ⛔️ This new error is not handled, causing an unhandled rejection.
throw new Error('A new error occurred in the catch block!');
}
}

doSomething();

Solution: Any function that might throw an unhandled error (even from a catch block) should itself be called within a try...catch block or have a .catch() chained to its promise.

doSomething().catch(finalError => {
console.error('Caught the final error:', finalError.message);
});

Conclusion

The UnhandledPromiseRejection error is a critical feature that helps you identify and fix bugs in your asynchronous code.

To solve it, you must ensure every Promise has an error handling path:

  • If you are using the .then() syntax, always chain a .catch() block.
  • If you are using async/await, which is the recommended best practice, always wrap your await calls in a try...catch block.

By consistently handling promise rejections, you can write more robust, reliable, and predictable asynchronous code.