Cannot extract error message from error.message - node.js

I have this line of code in my express app:
catch (err) {
res.status(500).send(err.message);
}
when i console log the error I get this message:
name: 'TokenExpiredError',
message: 'jwt expired',
but when I recieve the error in my client using axios request like so:
catch (err) {
console.log(err.message)
I get this : Request failed with status code 500
how can I access the original massage?

You don't want to simply catch the error, a 500 error is just a 500 error (with it's own generic message).
You need to extract the message you send in the response from the response body. This is from the github issues pages for axios https://github.com/axios/axios/issues/960:
axios
.post('ajax/register/otp', this.registerData)
.then(function (response) {
...
})
.catch(function (error) {
console.log(error.response);
});

Related

Axios delete giving 404 after deleting from database

I am sending a delete request using axios from my React frontend to node js express backend with mongo DB. Although the data does get deleted from my database but I still get an error 404 Not Found.
Here is React code
axios
.delete(`http://localhost:8000/notes/${id}`)
.then(res => {
console.log("The response is "+res.data)
})
.catch(err => {
console.log("There was an error "+ JSON.stringify(err.response))
});
Here is node js express code app.js
app.delete("/notes/:notesId", cors(), function(req, res) {
const query={_id:req.params.notesId};
console.log("The notes id is "+ query);
Note.findOneAndDelete(query, function(err) {
if(!err) {
console.log("The item got successfully deleted");
res.redirect("/");
} else {
console.log(err)
}
})
})
Please note that the entry gets deleted from my database but i get this error in my browser console :
xhr.js:178 DELETE http://localhost:8000/ 404 (Not Found)
App.jsx:26 There was an error {"data":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot DELETE /</pre>\n</body>\n</html>\n","status":404,"statusText":"Not Found","headers":{"content-length":"142","content-type":"text/html; charset=utf-8"},"config":{"url":"http://localhost:8000/notes/5ee130b65dc5f521acf60f38","method":"delete","headers":{"Accept":"application/json, text/plain, */*"},"transformRequest":[null],"transformResponse":[null],"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1},"request":{}}
I am trying to hit the complete url till notes id but it is only considering till root
Try modifying the res to send a 200 OK status if the object gets deleted. You could also send a message for your frontend to display in this manner
if(!err) {
res.status(200).json({ message: 'The item got successfully deleted', error: false });
} else {
res.status(500).json({message : 'Oops and error occurred', error : true});
Regardless a simple res.status(200).end(); should suffice as well for your situation.

How catch error message from server nodejs?

Sup guys! This is the code on server side when something goes wrong:
return res.status(400).send({ error: 'Email already used!'});
And this is my frontend code that I try to catch the error message:
return async dispacth => {
try {
const res = await axios.post('http://localhost:3333/account/signin', userData);
localStorage.setItem('JWT_TOKEN', res.data.token);
dispacth({
type: AUTH_SIGN_IN,
token: res.data.token
});
} catch (err) {
console.log(err.message)
console.error('error', err);
dispacth({
type: AUTH_ERROR,
errorMessage: err.message
});
}
}
But this is what I got on browser's console:
Try console.log(err.response) instead of console.log(err.message).
I'm new to Node and Axios, but using "err.response" after catching "err" fixed a very similar issue I had.
For res.status(400).send('Email already used!');
You could do:
console.log(error.response.data.message);
For the error message being sent as a JSON object like res.status(400).send({ error: 'Email already used!'});
You could do:
console.log(error.response.data.error);

Why can't I read message or status code on receiving 409 in response?

I'm using react in front end. Why cant I read data/message sent by the express when the status code is 409 or any 400 status code?
This is how I'm trying to read the response
hSubmit = event => {
console.log(this.state.checklistName)
event.preventDefault();
post.AddChecklistNames(this.state.token,this.state.category,this.state.checklistName)
.then(res=> {
if(res.status===201){
// window.location.reload(true);
}
else if(res.status===400||res.status===409||res.status===401||res.status===404||res.status===403){
console.log(res)
window.alert(res.data.error)
}
this.setState({checklistName:""})
})
What express is sending
response.status(409).json({ error: 'there is conflict'})
I can't read the error
res is not defined i guess. Try this:
.then(res=> {
if(res.status===201){
// window.location.reload(true);
})
.catch (err) {
console.log(err.response.data)
window.alert(err.response.data)
}
When returning error status code, response is treated as an error, so you should check error.response.data in a catch block
You need to catch error in catch block. In catch block you can see your error response and implement your logic accordingly

How to send email in the background using nodemailer for NodeJS application?

I am building an Angular 4 and Node application. Once any user registers on the front-end, I am storing their data in the database, and then would like to send them a successful registration email using the nodemailer package.
Here's the Node js code:
router.post('/', function(req, res, next) {
SOME_DATABASE_FUNC() {
if(FAILED_CASE) {
return res.status(500).json({
title: 'An error occurred',
status: 500,
error: error
});
var mailOptions {...}
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
return res.status(500).json({
title: 'An error occurred',
status: 500,
error: error
});
}
console.log('Message', info.messageId, info.response);
return res.status(200).json({
message: 'Emailed successfully',
details: info
});
});
}
}
});
This code works perfectly, but it takes few seconds to send the email, and the user has to wait to show the success response which doesn't seem to fit good. Instead I would like to send it in the background may be as an asynchronous function or like a cron job.
But I am not sure how to transform the code to send it as a job instead of sending and waiting after the database transaction. Please help me out with the issue.
send response outside block of transporter.sendMail. So it will not wait for process of email send to be completed.
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
return res.status(500).json({
title: 'An error occurred',
status: 500,
error: error
});
}
console.log('Message', info.messageId, info.response);
});
return res.status(200).json({
message: 'Emailed successfully',
details: info
});
use Process.nextTick() for sending email
We knew that nodejs request and response is stream and you can do stuff after sending response stream in this way response time will decrease and other stuff will continue asynchronously after sending response to client.
You can send response successfully to client and then you can call send mail function.

Error: Can't set headers after they are sent. - NodeJS and Express

I have a NodeJS Rest API where I have a user collection, besides that I do user SMS verification.
This is the controller for the POST /:id/verification
exports.verification = (req, res) => {
const id = req.params.id
return User.find(id)
.then( user => {
if (user.code !== req.body.code) {
res.json({ message: 'Incorrect code' })
res.sendStatus(500)
return
}
user.isVerified = true
user.save( error => {
if (error) {
res.json({ message: 'Failed to update user' })
res.sendStatus(500)
return
}
res.json({ user })
res.sendStatus(200)
} )
} )
.catch( error => {
res.json({ error })
} )
}
But the thing is that when I post to /:id/verification I get this error
Error: Can't set headers after they are sent. - NodeJS and Express
On this line:
res.json({ user })
res.sendStatus(200)
But I dont understand why, I dont send any response before this.
Can someone explain me what Im doing wrong?
you are using both res.json() and res.sendStatus() both together, both of them send response back, That is why it is showing error that Can't set headers after they are sent.
you should use only one of them.
If you want to send status along with the JSON response, you can try this:
res.status(500).json({ message: 'Incorrect code' });
Also, status of 200 is default when using res.send, res.json, etc. So you dont need to send status 200 with res.json()
res.json() send object to the clilent and after that you are trying to set the header with status code. So, it shows the error message. Use following code for set status and sending the content in the same time.
res.status(500).json({ error: 'message' } /* json object*/);

Resources