I'm getting UnhandledPromiseRejectionWarning when I run this simple code:
var d = new Promise((resolve, reject) => {
if (false) {
resolve('hello world');
} else {
reject('no bueno');
}
});
d.then((data) => console.log('success : ', data));
d.catch((error) => console.error('error : ', error));
The complete response is:
error : no bueno
(node:12883) UnhandledPromiseRejectionWarning: no bueno
(node:12883) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 2)
(node:12883) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Seems like d.catch() is being fired. I noticed that if comment out d.then(), the warning message disappears.
I'm calling the script from the terminal like node foobar.js.
Am I doing something wrong?
Tested with node v8.14, v10 and v11 under MacOS High Sierra.
d.then() creates a new promise that is rejected because d is rejected. That is the rejected promise that is not handled correctly.
You should chain .then and .catch instead:
d
.then((data) => console.log('success : ', data))
.catch((error) => console.error('error : ', error));
Related
currently I'm struggling with fingerprint in my previous project i solved this in this way:
const test = async (req, res, next) => {
// other code
const FingerprintJS = require('#fingerprintjs/fingerprintjs');
const store = require('store')
FingerprintJS.get({
preprocessor: function(key, value) {
return value
}
},function(components){
let values = components.map(function (component) { return component.value });
let device_id = FingerprintJS.x64hash128(values.join(''), 31);
store.set('print', { device: device_id })
});
await new Promise(resolve => setTimeout(resolve, 1000));
// other code
};
But now I cant set it up to work.. I'm getting error in console.log :
(node:4940) UnhandledPromiseRejectionWarning: TypeError: FingerprintJS.get is not a function
at login (C:\Users\PC06\Desktop\project\backend\controllers\clients-controllers.js:53:17)
(node:4940) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:4940) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a
non-zero exit code.
Any help for this?
I'm running an electron application with the nfc-pcsc module. When I hold my Android device close to the acr-122u, I get the following logging:
Running in development
18:52:19 – info: nfc module init
(node:30973) UnhandledPromiseRejectionWarning: Error: Cannot process ISO 14443-4 tag because AID was not set.
at ACR122Reader.handle_Iso_14443_4_Tag (/private/var/www/lab/electron-clientnfc/node_modules/nfc-pcsc/dist/Reader.js:566:26)
at ACR122Reader.handleTag (/private/var/www/lab/electron-clientnfc/node_modules/nfc-pcsc/dist/Reader.js:506:21)
at CardReader.Reader.reader.on (/private/var/www/lab/electron-clientnfc/node_modules/nfc-pcsc/dist/Reader.js:164:18)
(node:30973) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 1)
(node:30973) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
This is my code:
const { NFC } = require('nfc-pcsc');
const nfc = new NFC(); // optionally you can pass logger
nfc.on('reader', (reader) => {
console.log(`${reader.reader.name} device attached`);
reader.aid = 'F222222222';
reader.on('card', async card => {
console.log(`${reader.reader.name} card detected`, card);
});
reader.on('card.off', (card) => {
console.log(`${reader.reader.name} card removed`, card);
});
reader.on('error', (err) => {
console.log(`${reader.reader.name} an error occurred`, err);
});
reader.on('end', () => {
console.log(`${reader.reader.name} device removed`);
});
});
nfc.on('error', (err) => {
console.log('an error occurred', err);
});
what is wrong with this?
I'm using a 3rd party module that wraps around their API. I have the following code:
const api = require('3rdpartyapi');
async function callAPI(params) {
try {
let result = await api.call(params);
return result;
}
catch(err) {
throw err; //will handle in other function
}
}
async function doSomething() {
try {
//...do stuff
let result = await callAPI({a:2,b:7});
console.log(result);
}
catch(err) {
console.error('oh no!', err);
}
}
Despite both try-catch blocks, the 3rd party API, when it losses connection to homebase (happens quite frequently :( ), blows up with:
(node:13128) UnhandledPromiseRejectionWarning: FetchError: request to https://www.example.com failed, reason: getaddrinfo ENOTFOUND
Followed by:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 1)
How come none of my try-catch catch this? What exactly is unhandled, and how to actually handle this?
The point is the await only converts "first layer" rejection into error, however the promise can have promise inside, and their library may fail to catch the rejection inside. I have made a proof of concept 3rdpartyapi which can trigger the behavior you see:
(async function () {
// mock 3rdpartyapi
var api = {
call: async function(){
await new Promise((resolve, reject) => {
// why wrap a promise here? but i don't know
new Promise((innerResolve, innerReject) => {
innerReject('very sad'); // unfortunately this inner promise fail
reject('this sadness can bubble up');
})
})
}
};
// your original code
async function callAPI(params) {
try {
let result = await api.call(params);
return result;
} catch (err) {
throw err; //will handle in other function
}
}
async function doSomething() {
try {
//...do stuff
let result = await callAPI({
a: 2,
b: 7
});
console.log(result);
} catch (err) {
console.error('oh no!', err);
}
}
doSomething();
})();
Output:
$ node start.js
oh no! this sadness can bubble up
(node:17688) UnhandledPromiseRejectionWarning: very sad
(node:17688) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 1)
(node:17688) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I have an application where I continuously have to run some async code in the background. I created a minimal simulation of my application.
let promise_chain = Promise.resolve();
let rejected_promise_count = 0;
const interval_id = setInterval(
// Do some important polling. I will just always reject to demonstrate the problem.
() => {
promise_chain = promise_chain.then(() => {
rejected_promise_count += 1;
return Promise.reject();
})
},
10
);
// Set timeout simulates the program being done.
setTimeout(
() => {
clearInterval(interval_id);
promise_chain
.then(() => end("Resolved! :D"))
.catch(() => end("Rejected! D:"));
},
1000
);
function end(message) {
console.log(message);
console.log(`Amount of rejected promises created: `, rejected_promise_count);
}
This gives a long list of these:
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 2)
(node:29217) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 2)
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 3)
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 3)
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 4)
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 4)
Eventually ended by these:
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 87)
(node:29217) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 87)
(node:29217) UnhandledPromiseRejectionWarning: undefined
(node:29217) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). (rejection id: 88)
Rejected! D:
Amount of rejected promises created: 1
(node:30920) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 89)
I'm not quite sure why node doesn't want me to handle these asynchronously, but given it runs on an interval, I really have no other choice.
How do I get rid of the endless list of warnings, and more importantly, how do I make sure in the future node will not terminate this process because it thinks I am not handling the rejections?
It depends what you want to do, the correct way to handle it is like this:
const interval_id = setInterval(
() => {
promise_chain = promise_chain.then(() => {
rejected_promise_count += 1;
return Promise.reject();
});
//ignore error here, you catch it in the setTimeout
promise_chain.catch(ignore=>ignore);
},
10
);
That will output:
Rejected! D:
Amount of rejected promises created: 1
This because you reject the first time so the chain is broken and all other then are not executed.
If you would like to continue executing and want to know how many passed and failed you can do something like this:
//using actual results
let results = [];
//special Fail value to indicate rejected promise
let Fail = function(reason){this.reason=reason;};
let isFail = object=>(object&&object.constructor===Fail);
let isNotFail = object=>!isFail(object);
let promise_chain;
let somePromise = ()=>Promise.reject(new Error("Some reason"));
const interval_id = setInterval(
() => {
promise_chain = (promise_chain||somePromise())
.then(
result => {
results.push(result);
return somePromise();
}
)
.catch(//catch the rejection and return a Fail type value
error=>new Fail(error)
);
},
10
);
// Set timeout simulates the program being done.
setTimeout(
() => {
clearInterval(interval_id);
promise_chain
.then(
result => {
//add the last result to results
results.push(result);
console.log(
"rejected promises:",
results.filter(isFail).length
//you can get the errors like so:
//results.filter(isFail).map(fail=>fail.reason)
);
console.log(
"resolved promises:",
results.filter(isNotFail).length
//results.filter(isNotFail) is an array of resolved values
)
}
);
//this will never reject because we catch rejected promises
// and add fail types to results
// .catch(() => end("Rejected! D:"));
},
1000
);
I have a promise function called findProperty which in this case rejects like this:
reject('ERR: Unknown propertyID or inactive property in call of newBooking');
And this is my handler that calls findProperty:
async function main() {
var res = "";
try {
findProperty();
res = await findUser(userEmail);
res = await findUser(agentEmail);
res = await getUsers();
}
catch(err) {
console.error(err);
console.log(" newBooking: " + err);
callback( { error:true, err } );
}
}
main();
This causes the following error:
(node:10276) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ERR: Unknown propertyID or inactive property in call of newBooking
(node:10276) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I dont get this, I got my catch(err) shouldn't that be enough?
Just tried something, this works fine:
resolve('ERR: Unknown propertyID or inactive property in call of newBooking');
But this gives the error:
reject('ERR: Unknown propertyID or inactive property in call of newBooking');
If findProperty returns a promise, you need to await it in order to trigger the failure within the context of the async function; otherwise the rejection disappears into outer space.
To "fire and forget" without waiting, yet catch failures with your try/catch:
findProperty().catch(e => { throw e; });