node: add catch-function to promise after construction - javascript

Consider this code:
var p = new Promise(function(resolve, reject){
console.log("run");
setTimeout(reject, 5);
});
p.catch(function() {
console.log("cought!");
});
p.then(function() {
console.log("then!");
});
Output (browser):
run
cought!
Here, in the browser it behaves like expected. Bun ran as a node-script I get:
run
cought!
(node:13927) UnhandledPromiseRejectionWarning: undefined
(node:13927) 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:13927) [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.
So the rejection got catched, but node is still complaining - why that?
I could chain everything together as suggested here and here:
new Promise(function(resolve, reject){
console.log("run");
setTimeout(reject, 5);
}).then(function() {
console.log("then!");
}).catch(function() {
console.log("cought!");
});
Output (browser and node):
run
cought!
In my usecase I can't use this solution, because I have a factory-function which builds the Promise. The catch- and then-functions shall be attached by the factory's caller.In case of then-function it works, but not for catch. How could I avoid this warning?

Promises are multicast, so each time you call .then or .catch you get a new promise object (chain) back. That is, p.then and p.catch both return their own separate promise objects. This means that there is no catch path for p.then.
If chaining the promises together is not possible, then you'll have to handle the error in the new promise chain created by .then. You can swallow this exception if you so choose, but it is a separate exception:
p.then(function() {
console.log("then!");
}).catch(() => {});

I am using Async Await to solve this problem hope it helps, works fine in my computer.
const iReturnPromise = () => {
return new Promise((resolve, reject) => {
console.log("run");
setTimeout(reject, 5);
});
}
async function displayPromiseResults() {
try {
await iReturnPromise();
console.log('!then');
}
catch(ex) {
console.log("cought!");
}
}
displayPromiseResults();

Related

Unhandled promise rejection nodejs

I am trying to use openweather-apis to connect to a dialogflow agent. I am new to promises and I keep getting the warning UnhandledPromiseRejectionWarning and I'm not sure on how to fix this.
Currently I have 2 files weather.js, which makes the api call
const api = require("openweather-apis")
api.setAPPID(process.env.API_KEY)
api.setUnits("metric")
module.exports = {
setCity: function(city) {
api.setCity(city)
},
getWeather: function() {
return new Promise(function(resolve, reject) {
api.getTemperature(function(err, temp) {
if (err) reject(err)
resolve(temp)
})
})
}
}
And I make use of weatherinCity.js, which retrieves the city from the agent, calls the calling function and then sends a response to the user.
const weather = require("../../weather")
module.exports = {
fulfillment: function(agent) {
const city = agent.parameters.geo_city
weather.setCity(city)
weather.getWeather().then(function(temp) {
agent.add(
"It is ${temp} degrees Celcius in ${city}"
)
}).catch(() => {
console.error("Something went wrong")
})
}
}
full error message:
(node:2896) UnhandledPromiseRejectionWarning: Error: No responses defined for platform: DIALOGFLOW_CONSOLE
at V2Agent.sendResponses_ (C:\Users\Coen\Desktop\ciphix-ca-case\node_modules\dialogflow-fulfillment\src\v2-agent.js:243:13)
at WebhookClient.send_ (C:\Users\Coen\Desktop\ciphix-ca-case\node_modules\dialogflow-fulfillment\src\dialogflow-fulfillment.js:505:17)
at C:\Users\Coen\Desktop\ciphix-ca-case\node_modules\dialogflow-fulfillment\src\dialogflow-fulfillment.js:316:38
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:2896) 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:2896) [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 error indeed happened because this code fails to handle the Promise Rejection. While I'm not sure which Promise Rejection that failed to handle, but based on this and this GitHub discussions. It seems you need to return the agent.add() function.
I recommend trying async-await style with the consequence that you have to add a try catch block
module.exports = {
fulfillment: async function(agent) {
try {
const city = agent.parameters.geo_city
weather.setCity(city)
let temp = await weather.getWeather()
agent.add(
"It is ${temp} degrees Celcius in ${city}"
)
} catch (err) {
console.error("Something went wrong")
console.error(err)
}
}
}
Every error that is thrown on the try block should be caught in a catch block. Don't forget to add async before the function.
it will not solve your problem but generally speaking, i would add "return" after if(err). because otherwise the call to resolve would be done. in your particular case it will do no harm, as because of the nature of promises it will be ignored. but if you had written anything between reject and resolve it would have been executed.
// best practice
if (err) return reject(err)
for your problem, i've just tried this fast test to convice myself that even throws are catched by .catch() so i think you must be running a bad/old nodejs version, or the code you provided is not complete, and the failure is elsewere. I dont see any line pointing to your own code in the log O_o (only node_modules).
which nodejs version is it ?
var p = new Promise((resolve, reject) => {
throw new Error('test');
resolve('ok')
})
p.then(console.log).catch(function(err) {
console.error('err', err)
});

Node JS spawn child_process throws UnhandledPromiseRejectionWarning

I am trying to run an async CMD command on with my Node server. Unfortunately my functions always throws an UnhandledPromiseRejectionWarning. I searched for results but never found a solution that fits my code.
(node:20704) UnhandledPromiseRejectionWarning: 0
(node:20704) 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:20704) [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 know that the error states I should use a catch block but I really dont know how I should implement that with the lambda implementation I used.
const exec = require('child_process');
const execWindowsCommand = new Promise(async (resolve, reject) => {
const process = exec.spawn('cmd', [ '/c', 'dir' ]);
process.on('data', data => resolve(data));
process.on('error', err => reject(err));
process.on('close', err => reject(err));
process.on('unhandledRejection', function(reason, promise) {console.log(promise);});
});
app.get("/cmdWIN", async(req, res) => {
execWindowsCommand()
.then(function(value) {
console.log(value);
res.send(value);
})
.catch((error) => {
console.error(error);
res.send(error);
});
});

UnhandledPromiseRejectionWarning even when there is a .catch on promise [duplicate]

This question already has an answer here:
Weird behavior with Promise throwing "Unhandled promise rejection" error
(1 answer)
Closed 4 years ago.
i have the following problem that i can not figure out. here is my code:
//file1.js
module.exports = {
delete: function(id) {
return new Promise((resolve,reject) => {
setTimeout(() => {reject('bla bla');}, 2000);
});
}
}
//file2.js
const file1 = require('file1');
var delPr = file1.delete(id);
delPr.then(() => {
console.log('+++++++++++++++++++++++++++');
res.status(200).json({
message : "delete post"
});});
delPr.catch((error) => {
console.log('-----------------------------');
}
when this is the code i get:
-----------------------------
(node:102437) UnhandledPromiseRejectionWarning: bla bla
(node:102437) 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:102437) [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.
when changing my code in file2.js to :
file1.delete(id).then(() => {
console.log('+++++++++++++++++++++++++++');
res.status(200).json({
message : "delete post"
});}).catch((error) => {
console.log('-----------------------------');
});
});
everything works fine and i only get the '--------' in the console, can someone please explain what is the difference?? i don't see one, and iv'e been on it for the past 3 hours.
yes .then() returns a promise and that promise is not handled.
so when you do a.then().catch() then rejection on that promise is handled by the catch

Rejected promise still call to the next .then()

Here is a promise chain that rejects 100%. I expect the first console.log to print, but after that because of the rejected promise it should skips to .catch at the end
function stringProcessor(string)
{
return new Promise((resolve, reject) => {
console.log(`Calling ${string}`)
reject(`Rejected ${string}`)
});
}
exports.concat = functions.https.onRequest((request, response) => {
return stringProcessor("foo")
.then(stringProcessor("bar"))
.then(stringProcessor("hello"))
.then(response.send("no problem!"))
.catch(e =>
{
console.log("CAUGHT : " + e)
response.send("not ok")
})
})
However the output log is
info: User function triggered, starting execution
info: Calling foo
info: Calling bar
info: Calling hello
info: CAUGHT : Rejected foo
info: Execution took 15 ms, user function completed successfully
error: (node:67568) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Rejected bar
error: (node:67568) 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:67568) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Rejected hello
Not only that everything has been called sequentially, also I have been warned about uncaught promise even if the CAUGHT line clearly prints.
You need to pass function which returns promise in then:
return stringProcessor("foo")
.then(() => stringProcessor("bar"))
.then(() => stringProcessor("hello"))
// ...
In your example you are not passing functions, but promises.

When start code in Promise in Node.js ES6?

I make a method that create a promise for each element in array.
queries.push(function (collection) {
new Promise((resolve, reject) => {
collection.find({}).limit(3).toArray(function (err, docs) {
if (err) reject(err);
resolve(docs);
});
});
});
const getAnalyticsPromises = (collection) => {
let promises = [];
queries.each((item) => {
promises.push(item(collection));
});
console.log(queries);
return promises;
}
This code return this errors:
(node:10464) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: queries.each is not a function
(node:10464) 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.
The question is: When the promise is called? When i create it:
promises.push(item(collection));
or when i call it with then() function?
Well the error you have is about queries has not method each - you should use forEach instead.
Bescides you should return promise from your function:
queries.push(function (collection) {
return new Promise((resolve, reject) => {
collection.find({}).limit(3).toArray(function (err, docs) {
if (err) reject(err);
resolve(docs);
});
});
});
So when you call item(collection) where item is one of your anonymous functions, the promise would be created.
And now you can handle with it whatever you need, for example:
let p = item(collection);
p.then(...).catch(...)

Categories

Resources