Unhandled promise rejection nodejs - javascript

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)
});

Related

UnhandledPromiseRejectionWarning: TypeError: user.destroy is not a function (NodeJS- Sequelize)

I'm following a tutorial on NodeJs on youtube, but when it comes to deleting users by id, it doesn't work like what's on the tutorial. But on that video everything seems to work perfectly. This is my code. Where am I wrong? Looking forward to everyone's comments.
let deleteUserByID = (userId)=>{
return new Promise(async(resolve, reject)=>{
try{
let user = await db.User.findOne({
where: {id: userId}
})
if(user){
await user.destroy();
}
resolve();
}catch(e){
reject(e);
}
})
}
And this is the error displayed on the terminal screen:
(node:11140) UnhandledPromiseRejectionWarning: TypeError: user.destroy is not a function
at...
at...
at...
...
(Use `node --trace-warnings ...` to show where the warning was created)
(node:11140) 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:11140) [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.
After a while of searching on the internet, i found the solution, everything is working and seems to be fine, anyone can refer to it if they have the same error as mine.
Upvote if it works for you
let deleteUserByID=(userId)=> {
return db.User.destroy({ where: { id: userId } })
.then(rows => Promise.resolve(rows === 1))
}
Or another solution:
let deleteUserByID = (userId) => {
return new Promise(async (resolve, reject) => {
await db.User.findOne({
where: {
id: userId
}
})
await db.User.destroy({
where: {
id: userId
}
})
resolve({
errCode: 0,
message: `The user is deleted`
})
})
}

unhandled promis and node js upgrade to 16 though I use try catch

I am facing a very strange issue. As soon as I updated my node to node 16 from 14 my tests stopped working and I get a complain like this:
Error:
at /src/api/v1/datastore/SearchesDatastore.ts:109:25
at processTicksAndRejections (node:internal/process/task_queues:96:5)
And my code the line it shows is:
public async isRemovalNeeded() {
try {
this._logger.debug({message: `Checking if any design doc removal needed.`});
const designDocsName = getDesignDocLists(this.designDocsPath);
const allDesignDocs = await this._db.list({
include_docs: true,
startkey: "_design/",
endkey: "_design0"
});
const toBeRemoved = allDesignDocs.rows.
filter((row: any) => !designDocsName.includes(row.id.replace("_design/", "")));
return toBeRemoved.length > 0;
} catch (e) {
this._logger.warn({ message: "Failed to retrieve list of documents." });
this._logger.debug({ message: `Error: ${e}` });
throw new Error(errors.ERROR_GETTING_DB_LIST.message);
}
}
just to test I ran the same thing with node 14 and it passed with this warning
(node:22352) UnhandledPromiseRejectionWarning: Error:
at src/api/v1/datastore/SearchesDatastore.ts:128:19
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:22352) 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: 43)
(node:22352) [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 I am thinking it is because of node16 being strict for unhandled promises but in my code I Cannot see any unhandled promise so I am confused
any help is appreciated
Also this is how I call it :
try {
this._loggingService.debug({message: `Checking to see if current pod is a leader`});
const isLeader: any = await this._consensusService.isLeader();
this._loggingService.debug({message: `current Pod checked for leading and isLeader is: ${isLeader}`});
const isRemovalNeeded = await this._searchesDatastore.isRemovalNeeded();
this._loggingService.debug({message: `check occurred to make sure if design doc removal needed and isRemovalNeeded is: ${isRemovalNeeded}`});
const isUpdateNeeded = await this._searchesDatastore.isUpdateNeeded();
this._loggingService.debug({message: `check occurred to make sure if design doc update needed and isUpdateNeeded is: ${isUpdateNeeded}`});
if (!isRemovalNeeded && !isUpdateNeeded) {
shouldWait = false;
this._loggingService.info({ message: "All documents are up to date" });
} else if (isLeader) {
isRemovalNeeded && await this._searchesDatastore.cleanRemovedDesignDocs();
isUpdateNeeded && await this._searchesDatastore.syncAllDesignDocs();
shouldWait = false;
} else {
this._loggingService.info({ message: "Design docs are not synced but this pod is not a leader. We need to wait for leader pod to take do the house keeping first." });
}
if (!shouldWait) {
this._loggingService.debug({message: `datastorewatcher is done and we are proceeding to the next step...`});
this.watcherFailureCount= 1;
resolve(true);
break;
} else {
this._loggingService.debug({message: `datastorewatcher is not done. We will try again after ${config.databaseWatcher.interval}.`})
await this.sleep(config.databaseWatcher.interval);
}
} catch (e) {
this.watcherFailureCount++;
if(this.watcherFailureCount> config.databaseWatcher.toleranceLevel){
this._loggingService.warn({message: "App crashed and pod will die soon"})
reject(e);
break;
}
const nextIntervalToRun: number= config.databaseWatcher.interval * this.watcherFailureCount;
this._loggingService.warn({ message: `DataStoreWatcher failed but still failure is less than tolerance threshold: ${config.databaseWatcher.toleranceLevel}. Watcher will run again in ${nextIntervalToRun}. ${e}` });
await this.sleep(nextIntervalToRun);
}

How to throw an exception from a Promise to the Caller without an UnhandledPromiseRejectionWarning

Consider this database query handler that does contain a catch block:
async function dml(pool, sql, expected = -1) {
p(sql)
let rowCnt = await pool.query(sql)
.then(r => {
if (expected >= 0 && r.rowCount != expected) {
throw `DML [${sql}] had wrong number of results: ${r.rowCount} vs expected=${expected}`
} else {
return r.rowCount
}
})
.catch(err => {
msg = `Query [${sql}] failed: ${err}`;
printError(msg,err)
throw msg // THIS is the problem. It generates UnhandledPromiseRejection
}
return rowCnt
}
The thrown exception is intended to be caught by the caller here:
async function handleClip(data) {
..
// calling code
try {
// ...
let cnt = db.dmlClips(sql, 1) // Throw() happens in this invocation
debug(`Update count is ${cnt}`)
return rcode
} catch (err) {
// WHY is the thrown exception not caught here??
let msg = `Error in handleClip for data=${data.slice(0,min(data.length,200))}`;
error(msg,err);
}
But the above structure is not acceptable apparently: the following serious warning is generated:
(node:39959) UnhandledPromiseRejectionWarning: Query [insert into clip ...] failed: error: role "myuser" does not exist
at emitUnhandledRejectionWarning (internal/process/promises.js:170:15)
at processPromiseRejections (internal/process/promises.js:247:11)
at processTicksAndRejections (internal/process/task_queues.js:94:32)
(node:39959) 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:39959) [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.
at emitDeprecationWarning (internal/process/promises.js:180:11)
at processPromiseRejections (internal/process/promises.js:249:13)
at processTicksAndRejections (internal/process/task_queues.js:94:32)
So how does this need to be set up ? Note there is a related question here: how to properly throw an error if promise is rejected? (UnhandledPromiseRejectionWarning) . But for that question the asker did not have any exception handler/catch block.
You need to use await when you're calling the function db.dmlClips(sql, 1) so that it waits for the promise to be resolved/rejected. Change the line to let cnt = await db.dmlClips(sql, 1).
It looks like the try-catch block from which you are invoking db.dmlClips isn't inside an async function. Try-catch declared in functions without async keywords won't catch a promise rejection.

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 when using .reduce

const sendData = (response, language, locale) => {
try {
console.log(response.reduce((prev, curr) => prev + curr.confirmed, 0));
} catch (error) {
console.error('error');
}
};
and my fetch function:
const fetchGeneralData = async (param) => {
try {
let res = await axios.get(
`https://localhost/api/${param}`,
);
msg.reply(sendData(res.data.results), language, momentLocale);
} catch (error) {
msg.reply(language.errorMessage);
console.error(error, 'Error on fetchGeneralData');
}
};
The console.log shows me the correct value but for some reason, I still getting the errors.
I have tried adding async/await inside sendData but it did not work. My fetchGeneralData func works fine when i'm trying to return the date without modify it.
Here is the full message:
(node:5500) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: t.match is not a function
(node:5500) 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:5500) [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.

Categories

Resources