如何实现ExpressJS错误处理,根据HTTP状态码返回对应错误内容?
代码问题定位
- 核心方法认知偏差:
status()是响应对象res的专属方法,作用是给客户端返回的响应设置HTTP状态码,请求对象req上不存在该方法,原代码里写的req.status(403)属于无效调用,根本无法完成状态判断,甚至会直接抛出方法不存在的运行时错误。 - 中间件规则不匹配:Express识别的错误处理逻辑必须放在四参数签名的中间件里,也就是函数入参为
(err, req, res, next),普通三参数的前置中间件无法捕获通过next(err)传递的错误对象。 - 执行顺序逻辑错位:原代码把错误判断逻辑放在全局前置中间件里,在业务路由执行前就尝试判定状态,完全无法获取
/error路径下构造的错误对象,逻辑链路是断开的。
正确实现方案
第一步:实现/error路径的错误构造逻辑
在/error路由内,根据需要抛出的错误类型,给原生Error对象挂载自定义状态码属性,再通过next()把错误对象传递给后续处理流程,示例代码:
app.get('/error', (req, res, next) => { const err = new Error() // 可根据请求参数灵活匹配错误类型与对应状态码 switch(req.query.type) { case '403': err.statusCode = 403 break case '404': err.statusCode = 404 break case '500': err.statusCode = 500 break default: err.statusCode = 200 } // 把构造好的错误对象交给next处理 next(err) })
第二步:注册全局错误处理中间件
该中间件必须放在所有业务路由注册完成之后的最后位置,否则无法捕获路由抛出的错误。这个中间件负责专门捕获前面传上来的错误对象,根据错误携带的状态码返回对应提示:
// 错误处理中间件必须严格使用四参数签名,否则Express无法识别 app.use((err, req, res, next) => { // 读取错误对象上的状态码,无自定义值时默认返回500 const status = err.statusCode || 500 // 按状态码匹配对应提示内容 let content = '' switch(status) { case 200: content = '<h1>Connected!</h1>' break case 403: content = '<h1>ERROR FOUND</h1>' break case 404: content = '<h1>PAGE NOT FOUND</h1>' break case 500: content = '<h1>INTERNAL SERVER ERROR</h1>' break default: content = '<h1>Unknown Error</h1>' } // 设置响应状态并返回内容 res.status(status).send(content) })
避坑提醒
- 不要在响应逻辑执行后同时调用
next(),一旦res.send()完成响应返回,HTTP流程就已终止,重复调用会触发框架报错。 - 错误处理中间件的注册顺序不能错,必须放在所有业务路由、静态资源服务的注册之后,否则捕获不到路由抛出的错误。
- 不要在普通三参数中间件里做错误响应逻辑,这类中间件在请求到达路由前就执行,根本拿不到路由层构造的错误实例。
内容的提问来源于stack exchange,提问作者Dakshak
相关产品推荐
相关产品推荐

