Я использую пакет body-parser
вот так:
// For parsing application/json:
app.use(require('body-parser').json());
// For parsing application/x-www-form-urlencoded
app.use(require('body-parser').urlencoded({ extended: true }));
Когда получен действительный ввод, такой как { "foo": "bar" }
, все работает нормально, и я могу получить доступ к проанализированному объекту с помощью req.body
.
Однако при отправке недействительных данных (не в формате JSON):
data: JSON.stringify("just something inappropriate"),
Я получаю такую ошибку:
{ SyntaxError: Unexpected token " in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError
at ...
expose: true,
statusCode: 400,
status: 400,
body: '"Something"',
type: 'entity.parse.failed' }
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at ...
Как я могу правильно с этим справиться, чтобы сервер не выключился?
Добавьте обработчик ошибок, а затем настройте поведение способа по умолчанию для обработки этого erorr, по умолчанию будет сбой, как вы описываете.
app.use((err, req, res, callback) => {
// todo: implement error handling logic and return an appropriate response
console.error(err)
res.send(500)
callback()
})
Один из вариантов - добавить собственный промежуточное ПО обработчика ошибок и добавить проверку, чтобы отловить такие ошибки синтаксического анализа JSON:
app.use(require('body-parser').json());
app.use(require('body-parser').urlencoded({ extended: true }));
...
app.use((err, req, res, next) => {
// This check makes sure this is a JSON parsing issue, but it might be
// coming from any middleware, not just body-parser:
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
});
Другой вариант - обернуть промежуточное ПО body-parser
, чтобы отлавливать ошибки, исходящие только оттуда:
const bodyParser = require('body-parser');
app.use((req, res, next) => {
bodyParser.json()(req, res, err => {
if (err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
});
});
Или, если вы хотите повторно использовать эту функциональность для обнаружения различных ошибок от разных промежуточных программ, вы можете сделать:
function handleError(middleware, errorHandler) {
middleware(req, res, err => err ? errorHandler(err, req, res, next) : next());
}
const bodyParser = require('body-parser');
app.use(handleError(bodyParser.json(), (err, req, res, next) => {
if (err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
}));
Начиная с Express 4.16.0 - Дата выпуска: 2017-09-28, вы можете отлавливать разные ошибки из разных промежуточных программ, разделяя обработчик ошибок на другую функцию без использования Bodyparser, поскольку он устарел.
const app = express();
function handleError(middleware, req, res, next) {
middleware(req, res, (err) => {
if (err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
});
}
app.use((req, res, next) => {
handleError(express.json(), req, res, next);
});
Обратите внимание в коде Express 4.16.0 и выше, который выражает:
app.use(express.json()); // Without middleware error handling.
заменяет bodyParser:
app.use(bodyParser.json()); // Without middleware error handling.
Попробуйте прочитать обработку ошибок expressjs: expressjs.com/en/guide/error-handling.html, возможно, вам понадобится обработчик ошибок по умолчанию.