UnhandledPromiseRejectionWarning
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value. The Promise.reject() method returns a Promise object that is rejected with a given reason. The unhandledrejection event is sent to the global scope of a script when a JavaScript Promise that has no rejection handler is rejected; typically, this is the window, but may also be a Worker.UnhandledPromiseRejectionWarning
UnhandledPromiseRejectionWarning originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). A rejected promise is like an exception that bubbles up towards the application entry point and causes the root error handler to produce that output. It usually happens in async await functions, and there's an easy fix.
const functionName = async (arguments) => {
try {
// Your code here
} catch (error) {
// Handle rejection here
}
};
Rejected Promise
The original concept of promises was that you could have a rejected promise sitting around for some time before attaching a catch handler to it. For example, Firefox used to warn of uncaught rejection errors only when a rejected promise with no rejection handler was garbage collected from memory. Somebody decided that JavaScript developers couldn't be trusted with managing promise rejections properly and changed the HTML spec to require browsers to throw "UnhandledPromiseRejectionWarning" errors if a rejected promise has no rejection handlers added before code returns to the event loop.
On a case by case basis you can prevent the host being notified by adding a rejection handler that is never used. The reason is that adding a dummy rejection handler to a promise means that should it be rejected it has a rejection handler already - or if it was rejected the host is notified the promise now has a rejection handler - and you can call then and catch multiple times on the same promise.
catch(...) to a Promise
As defined in ES6, a promise is a state machine representation of an asynchronous operation and can be in one of 3 states: "pending", "fulfilled", or "rejected". The origin of UnhandledPromiseRejectionWarning lies in the fact that each and every promise is expected to handle promise rejection. This means that it should have a .catch(...) method. You can avoid the same by adding .catch(...) to a promise in the code as given below.
In the following code, the function promiseTest() will either resolve or reject a promise based on the value of a global variable globalVar:
var globalVar = false;
var promiseTest = function () {
return new Promise(function (resolve, reject) {
if (globalVar === true)
resolve();
else
reject();
});
}
var testFunc = promiseTest();
testFunc.then(function () {
console.log("Promise Resolved");
}).catch(function () {
console.log("Promise Rejected");
});
In some cases, the "UnhandledPromiseRejectionWarning" message comes even if you have .catch(..) written for promises. It's all about how you write your code. The following code will generate UnhandledPromiseRejectionWarning even though you are handling catch.
var globalVar = false;
var promiseTest = function () {
return new Promise(function (resolve, reject) {
if (globalVar === true)
resolve();
else
reject();
});
}
var testFunc = promiseTest();
testFunc.then(function () {
console.log("Promise Resolved");
});
// See the Difference here
testFunc.catch(function () {
console.log("Promise Rejected");
});
The difference is that you don't handle .catch(...) as chain but as separate. For some reason JavaScript engine treats it as promise without un-handled promise rejection. Promise.all
A nice way to wait for several Promises to resolve to use the Promise.all function. It expects an Array of Promises, and produces a Promise that resolves to an Array containing the values that the individual Promises resolved to. Furthermore, it only resolves after the last Promise resolves. If any of its input Promises rejects, then the entire Promise.all expression rejects as well. It effectively "runs" all of its input processes "at the same time", emulating the classic "fork-join" pattern.
Related Topics
- Uncaught TypeError: 'undefined' is not a function
- XMLHttpRequest cannot load no 'access-control-allow-origin'
- TypeError: null is not an object
- Uncaught RangeError: Maximum call stack size exceeded
- Uncaught TypeError: Cannot set property
- SecurityError: Blocked a frame with origin from accessing a cross-origin frame
- Unable to get property undefined or null reference
- SyntaxError: Cannot use import statement outside a module