Node.js - обрабатывать недопустимую ошибку JSON синтаксического анализатора тела - PullRequest
0 голосов
/ 29 октября 2018

Я использую пакет 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 ...

Как я могу правильно обработать это, чтобы предотвратить отключение сервера?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Один из вариантов - добавить пользовательское промежуточное ПО для обработки ошибок и добавить проверку для обнаружения ошибок синтаксического анализа 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();
}));
0 голосов
/ 29 октября 2018

Добавьте обработчик ошибок, а затем настройте поведение способа обработки этого erorr по умолчанию. По умолчанию будет происходить сбой, как вы описываете.

app.use((err, req, res, callback) => {
  // todo: implement error handling logic and return an appropriate response
  console.error(err)
  res.send(500)
  callback()
})
...