Node.js Express.js在路由未知的情况下忽略SyntaxError
在下面的express应用程序中: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,而不是通用中间件错误处理程序,它抛
- 使用无效的json数据执行POST for/push将导致HTTP 400错误发送回客户端
- 使用有效的json数据执行POST,但对于未知路由,将导致HTTP 404错误发送回客户端
- 对未知路由执行带有无效json数据的POST将导致HTTP 400错误发送回客户端
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()显式添加到每个路由。但对于我所需要的,它可以。谢谢,非常感谢。