node.js - 如果路由未知,Express.js会忽略SyntaxError

标签 node.js api express error-handling

在以下 express 应用中:

  • 使用无效的json数据执行/push的POST将导致HTTP 400错误发送回客户端
  • 使用有效的json数据执行POST,但是对于未知路由,将导致HTTP 404错误发送回客户端
  • 对未知路由执行带有无效json数据的POST,将导致HTTP 400错误发送回客户端

  • 我想要实现的是,在第三种情况下,还会发送404。换句话说,如果路由未知,我希望被app.post('*',(req,res,next))捕获,它将抛出404,而不是由通用中间件错误处理程序捕获,抛出400 json SyntaxError

    有什么办法可以做到这一点?
    const express = require('express');
    const { handleError, ErrorHandler } = require('./helpers/error');
    
    const app = express();
    
    app.use(express.json());
    app.use(express.urlencoded({extended: true}));
    
    app.get('/', function(req, res){
        res.send('Hello World');
    });
    
    app.post('/', function(req, res){
        console.log(req.body.data);
        res.sendStatus(200);
    });
    
    app.post('/push', function(req, res){
        console.log('push API');
        res.sendStatus(200);
    });
    
    app.post('*',(req, res, next) => {
        console.log('Unknown route');
        throw new ErrorHandler(404, 'API endpoint does not exist.');
       });
    
    app.use((err, req, res, next) => {
        console.log('Middleware error handling');
        handleError(err, res);
    });
    
    app.listen(3000, function(){
        console.log('Server started on port 3000')
    });
    

    error.js内容:
    class ErrorHandler extends Error {
        constructor(statusCode, message) {
          super();
          this.statusCode = statusCode;
          this.message = message;
        }
      }
    
    const handleError = (err, res) => {
        const { statusCode, message } = err;
        res.status(statusCode).json({
          status: "error",
          statusCode,
          message
        });
    };
    
    module.exports = {
        ErrorHandler,
        handleError
    }
    
    

    最佳答案

    通过将请求发送到不存在的路由,不会匹配您的任何处理程序。因此,您的错误处理中间件

    app.use((err, req, res, next) => {
        console.log('Middleware error handling');
        handleError(err, res);
    });
    

    直接执行。您可以做的是尝试在handleError函数中检测语法/解析错误。就像是:
    const handleError = (err, res) => {
        let {statusCode, message} = err;
    
        if (err.status === 400 && err.message.includes("Unexpected token")) {
            statusCode = 404;
        }
    
        res.status(statusCode).json({
            status: "error",
            statusCode,
            message
        });
    };
    

    编辑:

    可以通过仅对要解析json的路由使用json-parser中间件并将其删除为所有请求的常规中间件来解决此问题:
    ...
    //app.use(express.json());
    app.use(express.urlencoded({extended: true}));
    
    app.post('/', express.json(), function (req, res) {
        console.log(req.body.data);
        res.sendStatus(200);
    });
    
    app.post('/push', express.json(), function (req, res) {
        console.log('push API');
        res.sendStatus(200);
    });
    

    关于node.js - 如果路由未知,Express.js会忽略SyntaxError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62040670/

    相关文章:

    javascript - 如何让window.location.href执行POST请求

    node.js - 在 Windows 中构建 Node.js 模块

    java - API架构中断路器设计模式的优势是什么?

    node.js - 将服务器错误消息传递给客户端(使用 Express 和 Backbone)

    express - 如何使用 express-validator 中的 checkSchema 中间件验证嵌套的 POST 正文有效负载?

    javascript - 服务器从 Node 启动时如何运行 grunt?

    从浏览器进行 Node.js 和 Mocha 测试

    javascript - (MERN) 使用 Express.js 提供 React 应用程序的正确方法是什么?

    linux - 在 linux 上,如何通过系统调用或 shell 命令监视文件/目录的更改?

    Windows 消息循环异常