Unhandled promise rejections and ERR_HTTP_HEADERS_SENT - javascript

i'm trying to make a rest api server with node express and mysql, the structure of the requests is this:
this is the route
router.get('/api/courseDetails/:id', async (req, res) => {
try {
let levels = await db.levelsByCourseId(req.params.id)
res.sendStatus(200).json(levels)
} catch (e) {
console.log(e)
res.sendStatus(500)
}
})
and this is the query:
requests.levelsByCourseId = (id) => {
let query = "select * from levels where parent_course_id="+id+" and visibility>0"
return new Promise((resolve, reject) => {
pool.query(query,(err, results) => {
if (err) {
return reject(err)
}
return resolve(results)
})
})
}
i use this structure also for other requests that works without errore, but this gives me this error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at ServerResponse.header (C:\Users\giuse\VScodeProjects\noderest-tutorial-server\node_modules\express\lib\response.js:771:10)
at ServerResponse.json (C:\Users\giuse\VScodeProjects\noderest-tutorial-server\node_modules\express\lib\response.js:264:10)
at C:\Users\giuse\VScodeProjects\noderest-tutorial-server\server\routes\index.js:47:29
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
(node:15588) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
at ServerResponse.header (C:\Users\giuse\VScodeProjects\noderest-tutorial-server\node_modules\express\lib\response.js:771:10)
at ServerResponse.contentType (C:\Users\giuse\VScodeProjects\noderest-tutorial-server\node_modules\express\lib\response.js:599:15)
at ServerResponse.sendStatus (C:\Users\giuse\VScodeProjects\noderest-tutorial-server\node_modules\express\lib\response.js:357:8)
at C:\Users\giuse\VScodeProjects\noderest-tutorial-server\server\routes\index.js:50:13
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:15588) 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:15588) [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.
anyone could help me?
thank you
edit:
on the client side i have a promise and not some data (it is inside the promise)
Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "OK"
and the axios code:
static async getCourseDetails(id) {
try {
const data = await axios.get(basepath + '/api/courseDetails/' + id)
return data.data
} catch (error) {
throw error;
}
}

You used wrong method to set status before sending results to a client.
It should be like this:
res.status(200).json(levels)
Calling setStatus you actually do res.status(200).send('OK') and right after that you call json that also sets status 200 and send a result as JSON.

The issue lies in the way you send the response. In the try block you await the levels from the db and then use sendStatus set a status and with json(levels) send a response as JSON back.
But according to the docs of Express.js sendStatus does the following.
res.sendStatus(200) // equivalent to res.status(200).send('OK')
So the status is being sent as a response. And after that you send another response as JSON. This is what triggers the error.
Use res.status(200) instead to only set the status without sending it.
router.get('/api/courseDetails/:id', async (req, res) => {
try {
let levels = await db.levelsByCourseId(req.params.id)
res.status(200).json(levels)
} catch (e) {
console.log(e)
res.sendStatus(500)
}
})

Related

TypeError: cb is not a function in nodejs?

(node:13384) UnhandledPromiseRejectionWarning: TypeError: cb is not a function
I am using passport js for authentication for my website, I am able to get all routes but when I try to sign up that is post router so in the console I am seeing these err, my data saved in DB but after posting my page loading continuously.
here these err what I am getting
(node:13384) UnhandledPromiseRejectionWarning: TypeError: cb is not a function
at C:\Users\SBCS\Desktop\AppBlog\node_modules\passport-local-mongoose\index.js:247:59
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use node --trace-warnings ... to show where the warning was created)
(node:13384) 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:13384) [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.
and here is my post router code
app.post("/sign-up",(req,res)=>{
const username = req.body.username
const email = req.body.email
const password = req.body.password
User.register( {username:username}, req.body.email,req.body.password ,(err,user)=>{
if(err){
console.log(err);
res.redirect("/sign-up")
}else{
passport.authenticate("local" )(req,res, function (){
res.redirect('/compose')
})
}
})
and here is my mongoose connection
mongoose.connect('mongodb://localhost:27017/blog', {useNewUrlParser: true, useUnifiedTopology: true,useFindAndModify: false}).catch(err => console.log(err))
mongoose.set('useCreateIndex',true);
thanks
when I am getting err node js referring me this modules code see here
schema.statics.register = function(user, password, cb) {
// Create an instance of this in case user isn't already an instance
if (!(user instanceof this)) {
user = new this(user);
}
const promise = Promise.resolve()
.then(() => {
if (!user.get(options.usernameField)) {
throw new errors.MissingUsernameError(options.errorMessages.MissingUsernameError);
}
})
.then(() => this.findByUsername(user.get(options.usernameField)))
.then(existingUser => {
if (existingUser) {
throw new errors.UserExistsError(options.errorMessages.UserExistsError);
}
})
.then(() => user.setPassword(password))
.then(() => user.save());
if (!cb) {
return promise;
}
promise.then(result => cb(null, result)).catch(err => cb(err));
};
this is passport-local-mongoose module code
i got answer
this cause by
User.register( {username:username}, req.body.email,req.body.password ,(err,user)=>{
if(err){
line of code and after spending more time on it,I got some solution
solution is here
User.register({username: req.body.username}, req.body.password, function(err, user){
also if you want to send user name you can send it like this
User.register({username: req.body.username,name: req.body.registerName}, req.body.password, function(err, user){
thanks .....

Dialogflow fulfillment fetch not showing response

When I call the intent llamada the intent webhook triggers but it doesn't appear what I pass in the agent.add(json[0].name).
const express = require('express')
const app = express()
const {WebhookClient} = require('dialogflow-fulfillment');
const fetch = require('node-fetch')
let url = (ommited)
let settings = {method: "Get"};
app.get('/', function (req, res) {
res.send('Hello World')
})
app.post('/webhook', express.json() ,function (req, res) {
const agent = new WebhookClient({ request:req, response:res });
function llamada(agent) {
fetch (url, settings)
.then(res => res.json())
.then((json) => {
agent.add(json[0].name)
})
.catch((error) => {
assert.isNotOk(error,'Promise error');
});
}
let intentMap = new Map();
intentMap.set('llamada', llamada);
agent.handleRequest(intentMap);
})
app.listen(3000, () => {
});
I get this error:
ok
(node:9936) UnhandledPromiseRejectionWarning: Error: No responses defined for platform: DIALOGFLOW_CONSOLE
at V2Agent.sendResponses_ (C:\Users\aasensio\Desktop\Zerca\node_modules\dialogflow-fulfillment\src\v2-agent.js:243:13)
at WebhookClient.send_ (C:\Users\aasensio\Desktop\Zerca\node_modules\dialogflow-fulfillment\src\dialogflow-fulfillment.js:505:17)
at C:\Users\aasensio\Desktop\Zerca\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:9936) 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:9936) [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.
How can I make it to get in Dialogflow the response correctly?
The issue is that you're doing an asynchronous operation with a Promise, but agent.handleRequest() doesn't know to wait for the Promise to complete. So it tries to return a result to Dialogflow immediately, but the result hasn't been set yet.
In your case, addressing this is straightforward. You just need to return the Promise that is generated by the fetch().then()... chain. Something like this should work:
return fetch (url, settings)
.then(res => res.json())
.then((json) => {
agent.add(json[0].name)
})
.catch((error) => {
assert.isNotOk(error,'Promise error');
});

How to solve UnhandledPromiseRejectionWarning in NodeJS testing framework

I'm using custom commands in my testing framework based on Nightwatch.js. I want to do a PUT request via superagent. This os my custom command:
const superagent = require("superagent");
exports.command = function(url, header, body, callback) {
return superagent
.put(url)
.send(body) // sends a JSON post body
.set(header)
.then(result => {
callback(true, result);
return this;
})
.catch(err => {
if (err) {
callback(false, err);
return this;
}
});
};
And this command I'm using in my tests:
return client
.apiPut(apiUrl, header, body, function(status, result) {
assert.isTrue(status, "response status is false");
assert.isTrue(result.ok, "response result is NOT ok");
})
If everything is fine with the PUT request (status == true and successful response) then everything is fine and the test will finish, but if the PUT request is not successful (status != true and an error as result) I'm getting the following error message and the current Node process does not finish:
09:11:12 (node:103) UnhandledPromiseRejectionWarning: AssertionError: response status is false: expected false to be true
09:11:12 at /var/jenkins_home/jobs/MYJOB/workspace/testautomation/end2end-web-tests/pageobjects/MyPageView.js:59:20
09:11:12 at superagent.put.send.set.then.catch.err (/var/jenkins_home/jobs/MYJOB/workspace/testautomation/end2end-web-tests/commands/apiPut.js:14:9)
09:11:12 at <anonymous>
09:11:12 at process._tickCallback (internal/process/next_tick.js:189:7)
09:11:12 (node:103) 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)
09:11:12 (node:103) [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.
But I don't know what I'm doing wrong with the callback in my custom command. What should I do to solve that issue?
Thanks for the help. Now it is running. I've replaced the promise and replaced it completely with callbacks. Now it is working :)
const superagent = require("superagent");
exports.command = function(url, header, body, callback) {
return superagent
.put(url)
.send(body) // sends a JSON post body
.set(header)
.end((error, result) => {
if (error) {
callback(false, result, error);
} else {
callback(true, result, error);
}
});
};

How do I handle the UnhandledPromiseRejectionWarning in Node.JS

I have a few methods that use the request module to get images from URLs and returns it as a Promise, it works but when the image isn't found it rejects the promise with the status code 404. I looked into that warning and it is said that to handle the rejection you have to setup a catch callback after then() but I don't use then(), I use async/await.
This is the code to get the picture:
/**
* Returns picture from S3
* #param {String} filename Name of the file with extension
* #returns {String} Base64 string of the file
*/
getPictureFromS3: function (filename) {
return new Promise((resolve, reject) => {
let url = this.getURLFromS3(filename);
request(url, (err, res, body) => {
if (err) reject(err);
if (res.statusCode !== 200) {
reject(`Invalid status code <${res.statusCode}>`);
}
resolve(new Buffer.from(body).toString('base64'));
});
});
}
And this is how I call the method:
try{
socket.on('server get pictures', () => db.getPictures(data=>{
if(data!==null){
data.forEach(async e=>{
let picture = await utils.getPictureFromS3(e.getFilename());
});
}
}));
}catch(err){
console.log(err);
}
Full warning:
(node:256) UnhandledPromiseRejectionWarning: Invalid status code <404>
(node:256) 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:256) [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.
Using Node v10.14.2.
There are two problems here
You care trying to do async operation inside forEach which doesn't work with promises. You need to use for..of loop or Promise.all if you can do things in parallel.
The exception is raise inside the listener so it will not bubble up outside so your catch wouldn't be executed. You need to move your try catch inside. Something like this
socket.on("server get pictures", () =>
db.getPictures(data => {
if (data !== null) {
for(const e of data) {
try {
let picture = await utils.getPictureFromS3(e.getFilename());
} catch (err) {
console.log(err);
}
}
}
})
);

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