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"
}
If a client submits invalid / poorly formatted JSON to a Rails 3.2 or 4 app, a cryptic and unhelpful error is thrown and they’re left wondering why the request tanked. The error thrown by the parameter parsing middleware behaves differently depending on your version of Rails:
Catching Errors It’s important to ensure that Express catches all errors that occur while running route handlers and middleware. Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it.
If readFile causes an error, then it passes the error to Express, otherwise you quickly return to the world of synchronous error handling in the next handler in the chain. Then, the example above tries to process the data. If this fails then the synchronous error handler will catch it.
The default error handler. Express comes with a built-in error handler that takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack.
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: 404, message: err.message }); // Bad request
}
next();
});
Now I am able to send the desired response.
{
"status": 404,
"message": "Unexpected string in JSON at position 37"
}
Link to issue
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();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With