Node.js - обрабатывать недопустимую ошибку JSON парсера тела

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

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

Попробуйте прочитать обработку ошибок expressjs: expressjs.com/en/guide/error-handling.html, возможно, вам понадобится обработчик ошибок по умолчанию.

muradm 29.10.2018 16:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
10
1
12 080
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Добавьте обработчик ошибок, а затем настройте поведение способа по умолчанию для обработки этого 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.

Другие вопросы по теме