如何将4XX和5XX错误上报至Sentry?
解决Express中Sentry无法捕获4XX/5XX响应的问题
你的代码存在两个核心问题,导致Sentry无法捕获目标响应:
1. 直接返回状态码不会触发错误处理流程
res.sendStatus(502)这类写法仅设置HTTP响应状态码,不会抛出错误或触发Express的错误处理中间件。而Sentry的errorHandler仅处理通过next(error)传递的错误对象,自然捕获不到这类响应。
2. shouldHandleError逻辑存在疏漏
你当前判断statusCode > 400,会漏掉400状态码的错误。如果需要捕获所有4XX错误,应改为statusCode >= 400。
解决方案一:手动抛出错误并传递给next
在需要返回错误状态码的路由中,创建带状态码的错误对象,通过next()传递给错误处理中间件:
app.get('/',(req: any , res: any, next: any) => { const error = new Error('Bad Gateway'); error.statusCode = 502; next(error); })
同时修正shouldHandleError的逻辑:
function setSentryErrorHandler(app: Express) { app.use(Sentry.Handlers.errorHandler({ shouldHandleError(error) { // 捕获所有4XX和5XX错误 return error.statusCode >= 400; }, })); }
这种方法适用于你能主动控制错误抛出的场景,可让Sentry完整捕获错误上下文。
解决方案二:拦截响应状态码,手动上报Sentry
如果需要捕获所有路由中直接返回的4XX/5XX状态码(比如第三方路由或无法修改的代码),可添加响应拦截中间件,在响应发送前检查状态码并手动上报:
// 在所有路由定义之后、Sentry错误处理之前添加该中间件 app.use((req, res, next) => { const originalSend = res.send; const originalSendStatus = res.sendStatus; // 拦截res.send res.send = function(body) { if (res.statusCode >= 400) { const error = new Error(`HTTP Error ${res.statusCode}`); (error as any).statusCode = res.statusCode; Sentry.captureException(error); } return originalSend.call(this, body); }; // 拦截res.sendStatus res.sendStatus = function(statusCode) { if (statusCode >= 400) { const error = new Error(`HTTP Error ${statusCode}`); (error as any).statusCode = statusCode; Sentry.captureException(error); } return originalSendStatus.call(this, statusCode); }; next(); }); // 挂载Sentry错误处理器 setSentryErrorHandler(app);
该中间件会覆盖Express的res.send和res.sendStatus方法,在响应发送前检查状态码,发现4XX/5XX时自动创建错误对象并上报至Sentry。
内容的提问来源于stack exchange,提问作者noobie
相关产品推荐
相关产品推荐

