Reputation: 3810
I am getting SyntaxError: Unexpected string in JSON at position 59
error in html format when format of json data is not valid.
I don't know why it is giving me html instead of error object.
I have set my header like below.
//header middlewares
app.use((req, res, next) => {
res.setHeader('Content-Type', 'application/json');
res.setHeader("Access-Control-Allow-Origin", "*");
next();
});
I want to catch the error and send a message in below format.
{
"status":404,
"message":Unexpected string in JSON at position 59
}
Here is the error that I get.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>SyntaxError: Unexpected string in JSON at position 59<br> at JSON.parse (<anonymous>)<br> at parse (C:\Users\mydirectory\auth\node_modules\body-parser\lib\types\json.js: 89: 19)<br> at C:\Users\mydirectory\auth\node_modules\body-parser\lib\read.js: 121: 18<br> at invokeCallback (C:\Users\mydirectory\auth\node_modules\raw-body\index.js: 224: 16)<br> at done (C:\Users\my-directory\auth\node_modules\raw-body\index.js: 213: 7)<br> at IncomingMessage.onEnd (C:\Users\mydirectory\auth\node_modules\raw-body\index.js: 273: 7)<br> at IncomingMessage.emit (events.js: 203: 15)<br> at endReadableNT (_stream_readable.js: 1145: 12)<br> at process._tickCallback (internal/process/next_tick.js: 63: 19)</pre>
</body>
</html>
I tried catching this error.
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
console.error(err);
return res.status(400).send(err); // Bad request
}
next();
});
But the response that I get now is like below.
{
"expose": true,
"statusCode": 400,
"status": 400,
"body": "{\n\t\"username\":\n}",
"type": "entity.parse.failed"
}
Upvotes: 22
Views: 15452
Reputation: 3810
I posted this question on expressjs github repo, and I got a nice and reasonable solution.
If you want that specific response, that is what you need to send in your error handler instead of the err object itself.
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
console.error(err);
return res.status(400).send({ status: 400, message: err.message }); // Bad request
}
next();
});
Now I am able to send the desired response.
{
"status": 400,
"message": "Unexpected string in JSON at position 37"
}
Upvotes: 28
Reputation: 5699
if you want to catch all errors thrown by body-parsr for example entity.too.large or encoding.unsupported
just place this middleware right after your body-parser initialization
$ npm i express-body-parser-error-handler
https://www.npmjs.com/package/express-body-parser-error-handler
for example:
const bodyParserErrorHandler = require('express-body-parser-error-handler')
const { urlencoded, json } = require('body-parser')
const express = require('express')
const app = express();
router.route('/').get(function (req, res) {
return res.json({message:"🚀"});
});
// body parser initilization
app.use('/', json({limit: '250'}));
// body parser error handler
app.use(bodyParserErrorHandler());
app.use(router);
...
Upvotes: 0
Reputation: 2808
You will have to handle parsing error separately like below:
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
if (err.type === 'entity.parse.failed') {
let data = req.body || req.query;
try {
JSON.parse(data); // <-- reproduce error in order to catch it
} catch (error) {
// get the first line of error which is "SyntaxError: Unexpected string in JSON at position 59"
let message = error.toString().split("\n")[0];
return res.status(400).send({ status: 400, message: message }); // Bad request
}
}
else return res.status(400).send(err); // Bad request
}
next();
});
Upvotes: 4
Reputation: 785
Try creating an object to store the error details you want and return those as json...
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
let formattedError = {
status: err.statusCode,
message: err.message
}
return res.status(err.statusCode).json(formattedError); // Bad request
}
next();
});
Upvotes: 0