Node.js-处理正文解析器无效的JSON错误

时间:2018-10-29 15:19:46

标签: javascript node.js express error-handling body-parser

我正在像这样使用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 ...

如何正确处理此问题以防止服务器关闭?

3 个答案:

答案 0 :(得分:4)

一种选择是添加自定义error handler middleware并添加检查以捕获像这样的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();
}));

答案 1 :(得分:1)

添加错误处理程序,然后自定义处理该erorr的默认方式的行为,默认方式将按照您的描述崩溃。

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

答案 2 :(得分:1)

从 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.