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);
Related
I am using a node route and I use a trycatch block but Node.js is not having it. When there is an error with the code and it goes to the catch, it fails.
try {
...
res.send({ message: 'All good nothing wrong with the code above' })
} catch {
res.status(500).send({ message: 'There is an error I want to send to the front end' })
}
Node clearly is not happy about this, I know I cannot send res.send()twice but it is on a trycatch block. How do I send an error message back the front end if something fails?
Node complains with on the catch block:
'Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client'
UPDATE
I fixed it by sending the error object with throw to the catch block and not to use res.send() on the try catch for any conditional other than just once
It is always good to terminate the execution flow of the function when you want to send something and not do anything else afterwards.
res.send('All ok');
console.log('Response sent');
return;
or
return res.send('All ok');
try {
throw Error('Oops')
return res.send('OK')
} catch(error) {
return res.send('Not OK: ' + error.message)
}
You can't use two times res.send so add return.
try {
...
} catch {
res.status(500).send({ message: 'There is an error I want to send to the front end' })
return;
}
res.send({ message: 'All good nothing wrong with the code above' })
I am creating a NodeJS API using Express, PostgreSQL in which I created a controller function which will check the user from the database.
const checkUser = async (req, res) => {
try {
const user = await pool.query('select * from users where email = $1', [req.body.email]);
if (user.rows.length === 0) throw new Error('Error Found');
return res.json("User Found");
} catch (e) {
//======= Output at console ========
//Error: Error Found
console.log(e);
//======== Response Object Received From API ==========
// {
// "msg": "Error Found",
// "Error": {}
// }
res.status(400).send({ msg: 'Error Found', Error: e });
}
};
Consider the situation that the user is not found in the Database so from try block the control passes to the catch block.
1- I am not able to get why the Error thrown from the try block to catch block sends back an empty object as a response. Also, at the same time using console.log prints the correct output value in the console.
2- I want a fix so that I can send e as a response to the User.
The problem is that Error objects are not that easy to serialize (which is intentional). This...
try {
throw new Error('Catch me if you can');
} catch(e) {
console.log(JSON.stringify(e)); // {}
}
... just logs {}, the same as for empty object, because Error objects don't have enumerable properties. And in your case, you don't send that object directly - but make it a property of another object sent to client.
However, there are several ways out of this. If you always need your client to get all the details of an Error, cast that to string (as toString() is overridden):
try {
throw new Error('Catch me if you can');
} catch(e) {
console.log(JSON.stringify(e.toString())); // "Error: Catch me if you can"
}
... or use Error object properties - name and message - as separate fields of your response:
res.status(400).send({
name: e.name || 'Anonymous Error',
msg: e.message || 'no message provided'
});
As sub-approach, you might consider choosing your status code based on type of error you have (always sending 404 for 'not founds', for example).
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);
});
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.
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*/);