如何让Express服务器捕获JWT过期错误且不终止服务?
问题分析
你的代码存在两个核心问题,导致JWT令牌过期时Express进程直接中断:
- 首先调用了同步版
jwt.verify(payload, SECRET),这个方法在验证失败(比如令牌过期)时会直接抛出未捕获异常,没有任何错误处理逻辑,直接导致进程崩溃。 - 同步验证抛出错误后,后续的异步
jwt.verify调用根本不会执行,自然无法返回错误响应给Angular前端。
解决方案
方案1:移除冗余同步验证,完善异步回调错误处理
直接保留异步版jwt.verify,它会通过回调返回错误,不会直接抛出异常:
exports.someFunction = async (req, res, next) => { jwt.verify(payload, SECRET, function(err, decoded) { if (err) { // 精准判断错误类型,返回对应提示 if (err.name === 'TokenExpiredError') { return res.status(401).json('令牌已过期'); } return res.status(400).json('身份验证失败'); } return res.status(200).json('验证成功'); }) }
方案2:用async/await+try/catch处理同步验证
如果偏好同步写法,必须用try/catch包裹验证逻辑,捕获所有可能的异常:
exports.someFunction = async (req, res, next) => { try { const decoded = jwt.verify(payload, SECRET); return res.status(200).json('验证成功'); } catch (err) { if (err.name === 'TokenExpiredError') { return res.status(401).json('令牌已过期'); } return res.status(400).json('身份验证失败'); } }
方案3:添加全局错误处理中间件(生产环境必备)
为防止其他未捕获异常导致进程崩溃,在Express应用的所有路由之后添加全局错误处理中间件,兜底处理所有错误:
app.use((err, req, res, next) => { console.error(err.stack); if (err.name === 'TokenExpiredError') { return res.status(401).json('令牌已过期'); } res.status(500).json('服务器内部错误'); });
关键注意点
- 同步
jwt.verify会直接抛出异常,必须用try/catch捕获;异步版本通过回调返回错误,不会中断进程。 - 生产环境必须配置全局错误处理中间件,避免单个接口的未捕获异常导致整个服务崩溃。
- 可通过
err.name精准识别JWT错误类型(如TokenExpiredError、JsonWebTokenError),返回更精准的提示信息。
内容的提问来源于stack exchange,提问作者SolisQuid
相关产品推荐
相关产品推荐

