Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Express.js在路由未知的情况下忽略SyntaxError_Node.js_Api_Express_Error Handling - Fatal编程技术网

Node.js Express.js在路由未知的情况下忽略SyntaxError

Node.js Express.js在路由未知的情况下忽略SyntaxError,node.js,api,express,error-handling,Node.js,Api,Express,Error Handling,在下面的express应用程序中: 使用无效的json数据执行POST for/push将导致HTTP 400错误发送回客户端 使用有效的json数据执行POST,但对于未知路由,将导致HTTP 404错误发送回客户端 对未知路由执行带有无效json数据的POST将导致HTTP 400错误发送回客户端 我想实现的是,在第三个场景中,也会发送404。换句话说,如果路由未知,我希望app.post(“*”,(req,res,next))捕获路由,它将抛出404,而不是通用中间件错误处理程序,它抛

在下面的express应用程序中:

  • 使用无效的json数据执行POST for/push将导致HTTP 400错误发送回客户端

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

  • 对未知路由执行带有无效json数据的POST将导致HTTP 400错误发送回客户端

我想实现的是,在第三个场景中,也会发送404。换句话说,如果路由未知,我希望app.post(“*”,(req,res,next))捕获路由,它将抛出404,而不是通用中间件错误处理程序,它抛出400 json语法错误

有什么办法可以做到这一点

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解析器中间件,并将其作为所有请求的通用中间件删除,即可解决此问题:

...
//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);
});

通过向不存在的路由发送请求,所有处理程序都不匹配。因此,您的错误处理中间件

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解析器中间件,并将其作为所有请求的通用中间件删除,即可解决此问题:

...
//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);
});

请输入HandleError和ErrorHandler.js的内容以添加helpers/error.js的内容请输入HandleError和ErrorHandler.js的内容以添加helpers/error.js的内容谢谢,但是如果现有路由发生语法错误怎么办?如何区分现有路由的SyntaxError(需要生成HTTP 400)和非现有路由的SyntaxError(需要生成HTTP 404)。我相信通过上面的代码,所有带有消息“unexpected token”的syntaxerro都将生成HTTP404,即使是对于现有路由?如果我错了,请纠正我…谢谢,也许可以用另一种更通用的方式来描述它:我有两个错误代码,HTTP 400表示语法错误,HTTP 404表示不存在的路由。如果不存在的路由出现语法错误,我想赋予HTTP 404“优先级”,并将其发送到客户端。我已经编辑了我的答案,我认为它现在应该可以工作了,但我对解决方案并不完全满意。也许我会想出更好的办法。对你有用吗?您需要通过检查处理程序中的状态/消息来删除我的第一个建议。只需将您的
expres.json()
中间件移动到您想要处理json的路由处理程序中即可。它可以工作,只是认为可能会有一种更通用的方法,而不是将express.json()显式添加到每个路由。但对于我所需要的,它可以。谢谢,非常感谢。谢谢,但如果现有路线发生语法错误怎么办?如何区分现有路由的SyntaxError(需要生成HTTP 400)和非现有路由的SyntaxError(需要生成HTTP 404)。我相信通过上面的代码,所有带有消息“unexpected token”的syntaxerro都将生成HTTP404,即使是对于现有路由?如果我错了,请纠正我…谢谢,也许可以用另一种更通用的方式来描述它:我有两个错误代码,HTTP 400表示语法错误,HTTP 404表示不存在的路由。如果不存在的路由出现语法错误,我想赋予HTTP 404“优先级”,并将其发送到客户端。我已经编辑了我的答案,我认为它现在应该可以工作了,但我对解决方案并不完全满意。也许我会想出更好的办法。对你有用吗?您需要通过检查处理程序中的状态/消息来删除我的第一个建议。只需将您的
expres.json()
中间件移动到您想要处理json的路由处理程序中即可。它可以工作,只是认为可能会有一种更通用的方法,而不是将express.json()显式添加到每个路由。但对于我所需要的,它可以。谢谢,非常感谢。