Dropbox's `filesGetTemporaryLink` throws an uncatchable `UnhandledPromiseRejectionWarning` and terminates Node.js - javascript

To get a download link to the file hosted on Dropbox, I'm using a Dropbox JavaScript API (7.0.0):
export const fileDownload = async function fileDownload(fileUUID) {
let isSucceeded;
let message;
let file;
const dbx = _dropboxFactory();
try {
const operationResult = await dbx.filesGetTemporaryLink({
path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`
});
if ("OK" === http.STATUS_CODES[operationResult.status].toUpperCase()) {
file = Object.freeze({
length: operationResult?.result?.metadata?.size,
link: operationResult?.result?.link,
mime: mime.lookup(operationResult?.result?.metadata?.name),
name: operationResult?.result?.metadata?.name
});
isSucceeded = true;
message = SYS_MESSAGES.storageFileDownloadSucceeded.code;
} else {
isSucceeded = false;
message = SYS_MESSAGES.storageFileDownloadFailed.code;
}
} catch (err) {
file = "error";
isSucceeded = false;
message = "FIL_NOT_FOUND";
}
const downloadResult = Object.freeze({
file,
isSucceeded,
message
});
return downloadResult;
};
The problem is that when the path to the file is wrong, I get a Node.js exception:
(node:9156) UnhandledPromiseRejectionWarning: #<Object>
(node:9156) 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: 2)
(node:9156) [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've tested several options and came to conclusion that the issue is in:
const operationResult = await dbx.filesGetTemporaryLink({
path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`
});
My questions:
Why does Node.js claim «unhandled promise rejection» or «promise which was not handled with .catch()» and throws an UnhandledPromiseRejectionWarning exception if the code, which generates it is wrapped by try-catch?
Starting Node.js 15.x.x, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. Therefore, how to avoid UnhandledPromiseRejectionWarning?
A temporal workaround:
To run Node.js with a flag --unhandled-rejections=warn.
This will prevent the termination of the Node.js process with a non-zero exit code upon UnhandledPromiseRejectionWarning.

The problem was in the Dropbox library and has been solved by the Dropbox team with the release of 7.1.0. After upgrading the code in the question works correctly.

try changing your fileResponse function to something like this. You are mixing up async/await with .then().catch() style syntax.
Just wrap your function in a try-catch
async function getDocument() {
try {
const response = await fetch(`${http() + ip}/downloadDocument`, {
body: JSON.stringify({fileUUID: oModel.oData[0].documentFile}),
cache: "no-cache",
credentials: "same-origin",
headers: {
"Content-Type": "application/json"
},
method: "POST",
mode: "cors"
});
const data = await response.json();
return data;
} catch(err) {
console.log(err);
}
}

Related

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

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

How to pass read data from await readFile to writeFile in fs module of node.js?

In this code, file is being opened and read successfully.
var objFs = require('fs')
async function openFile() {
await objFs.open('new.js', 'r', (argError, argFD) => {
if (argError)
throw -1
else
console.log("File opened!")
})
// This object is the promise.
const objReadResult = await objFs.readFile('new.js', (argError, argData) => {
if (argError)
throw 2
else
console.log('File read!')
})
await objFs.writeFile('new.js', (argError, objReadResult) => {
try
{
if( argError )
throw argError
else
console.log("File written")
}
catch( arg )
{
console.log(arg)
}
})
}
openFile()
What is the way to extract the data from await of readFile and pass it to writeFile?
The way I have written the writeFile function is producing the following error:
(node:21737) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
at maybeCallback (fs.js:145:9)
at Object.writeFile (fs.js:1332:14)
at openFile (/home/sulakshana/Documents/nodejs/programs/async_await.js:29:14)
(node:21737) 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:21737) [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.
File opened!
File read!
Few issues I can see:
there is a mix of syntaxes - async/await while also providing callbacks to the fs calls;
no need to call fs.open before fs.readFile;
there are no data to be written in fs.writeFile [docs];
there should be await-ing at the end;
and the final (the actual error reported) - there should be try...catch block to catch and react to any errors that occur.
Example implementation:
const fs = require('fs').promises;
async function openFile() {
const objReadResult = await fs.readFile('new.js');
console.log('File read!');
await fs.writeFile('new.js', /* PROVIDE DATA TO WRITE */);
console.log('File written');
}
(async () => {
try {
await openFile();
console.log('Program is done');
} catch (err) {
console.error(err);
}
})();

I can not send an email to the mail

I can’t send email to. When registering, you must send a letter to the mail to confirm it.
I get an error: Callback must be a function at maybeCallback
const fs = require('fs');
const path = require('path');
let path_file = path.join(__dirname, '/views/email_templates/confirm_email.html');
let html_file = await fs.readFile(path_file, { encoding: 'utf-8' });
let html = await html_file(path_file);
let template = handlebars.compile(html);
let replacements = {
target_link: link,
password: merchant_password,
};
let htmlToSend = template(replacements);
let mailOptions = {
from: config.transport.user,
to : merchant_email,
subject : 'Please confirm your Email account and login password',
html : htmlToSend,
};
smtpTransport.sendMail(mailOptions);
What's my mistake?
(node:14300) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
at maybeCallback (fs.js:128:9)
at Object.readFile (fs.js:277:14)
at readFile (C:\Users\User\Documents\backend\src\controllers/merchants.js:299:38)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:14300) 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:14300) [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.
fs.readFileSync(...)
Try using a synchronous way for reading the file.
Error is pretty much clear. you must pass callback function to send method
smtpTransport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log('error occurred while sending');
console.log(error);
return;
}
console.log('Message sent:');
});

UnhandledPromiseRejectionWarning when using a SoapClient

I am new in node.js, and I am experimenting things recently. A few days ago, I have tried to send a XML request to an API, with the use of easysoap-request. It worked perfectly, but I would have had to create an XML file for each different query, so I tried with easysoap. I found myself stuck pretty quickly, but I managed to resolve some issues with the help of this website. Now my program give an error that I have trouble understanding. Here my code first:
const EasySoap = require('easysoap');
const request = (async () => {
const params = {
host : 'https://someapi.com',
path : '/dir/soap',
wsdl : '/dir/wsdl',
headers: [{
'user-agent': 'Request-Promise',
'Content-Type': 'text/xml',
}]
}
var soapClient = EasySoap(params);
soapClient.call({
method :'one_methode',
attributes: {
xmlns: 'https://someapi.com'
},
params: {
'api' : {
'authentication' : {
'login' : 'mylogin',
'password' : 'mypassword'
},
'params' : {
'another_params' : {
'name' : 'Brian',
}
}
}
}
}).then((callResponse) => {
console.log(callResponse.data); // response data as json
console.log(callResponse.body); // response body
console.log(callResponse.header); //response header
}).catch((err) => {
throw new Error(err);
});
});
request();
And the error it give me:
node:10264) UnhandledPromiseRejectionWarning: Error: Error: no wsdl/xml response at soapClient.call.then.catch (C:\Users\user\Documents\src\script.js:40:15) at process._tickCallback (internal/process/next_tick.js:68:7) (node:10264) 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:10264) [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.
Is this a problem with the .catch() ? Can someone explain me ? Thanks
It's because you're throwing error inside catch, which is wrapped to Promise.reject since it's thrown inside async function, and not catching anywhere.
...
}).catch((err) => {
throw new Error(err);
});
You can either handle the error in that block like console.error(err)
or handle in your request() function call like
// request returns promise since you wrapped it in async function
request()
.catch(err => console.error(err))

Categories

Resources