Express,通过中间件,如何全局捕获错误?改写异常结果
发布于 作者:苏南大叔 来源:程序如此灵动~Express
中间件如果抛出了错误,那么,在对应的路由内部是无法捕获错误的。因为,路由内部的逻辑是直接越过的。直接走向express
请求结束。那么,本文就这种情况进行简单的讨论。如何全局捕获express
的错误信息呢?包括路由内部以及中间件里面的错误信息。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:nodejs@20.18.0
,express@4.21.2
,jsonwebtoken@9.0.2
,express-jwt@8.5.1
。本文说的是express
错误全局掌控,不管哪里抛出了错误,都能捕捉到,并做出调整。
用魔法解决魔法
Express
,可能会抛出错误的地方,有三个:
- 路由逻辑内部,可捕获。
- 中间件内部,可捕获。
- 路由定义外部,代码顶层。但是这种情况下,
express
也运行不起来。
用中间件来捕获中间件的错误,重点就是【用来捕获的中间件的位置】,建议把它放在所有路由的最后面。下面中间件的代码位置,将部分影响本文的结论。
app.use((err, req, res, next) => {
console.log(req.url); // /refresh
console.log(req.method); // get
// ...
console.log(err.name); // UnauthorizedError
console.log(err.code); // invalid_token
console.log(err.status); // 401
console.log(err.message); // jwt malformed
// ...
});
后续逻辑走向可以使用的依据,就是req
和err
。如果是个自定义的错误类型,就可以通过其.name
进行判断。本文的目标错误类型就是UnauthorizedError
,它就是express-jwt
中间件所发出的错误异常名称。
方案一,抛出一个新的异常
只是修改一下错误代码和消息,抛出一个被修改的错误。
res.status(401).send("无效的Token");
例如:
app.use((err, req, res, next) => {
if (err.name === "UnauthorizedError") {
return res.status(401).send("无效的Token");
}
return res.status(500).send("未知错误");
});
方案二,正常输出json【推荐】
截获错误的目的,就是最大限度的保证服务器端的异常代码(非200
状态码)。所以,推荐使用这个方案。把标红的异常请求,转化为普通的200
请求。
return res.send({
status: 401,
message: "无效的Token",
});
例如:
app.use((err, req, res, next) => {
if (err.name === "UnauthorizedError") {
return res.send({
status: 401,
message: "无效的Token",
});
}
return res.send({
status: 500,
message: "未知错误",
});
});
这个例子的返回值,很容易误导大家得到的是个error
。所以,实际应用的时候,可以做些变通。
方案三,next()转下一个路由
正常的走向下一个逻辑,期待后面还有个能处理请求的路由。
- 如果本文所述中间件,位于所有的路由的最后方的话,下一个逻辑就只能是
404 not found
了。 - 如果本文所述中间件,后面还有一个能承载的路由的话,那么也许还能处理。
next()
方案四,next(err)转下一个中间件
带着err
走向下一个逻辑,期待后面还有个能处理err
的中间件。
next(err)
为了捕获错误,已经把这个中间件安排到所有路由的最后面了。所以,next()
的话,也是个404
的结果。但是,如果把这段异常捕获中间件,放在路由定义的中间,这个next()
还是有可能匹配到新的代码逻辑的。这个时候,next()
就有些意义。
题外话
所以,express
里面,定义两个相同路由,并不会产生覆盖关系。但是,也不会产生先后执行的关系。除非由这种错误捕获中间件,进行串联,后续再讨论吧。
相关文章
- https://newsn.net/say/express-json.html
- https://newsn.net/say/express-formidable.html
- https://newsn.net/say/express-body-parser.html
- https://newsn.net/say/express-middleware.html
- https://newsn.net/say/express-html.html
- https://newsn.net/say/express.html
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。