Sentry 默认不捕获 Node 未捕获异常,必须显式启用 OnUncaughtException 和 OnUnhandledRejection 集成,并确保 Sentry.init() 在入口文件最顶部同步执行,早于任何业务代码;VSCode 调试需配置 launch.json 的 console 为 integratedTerminal 并验证 environment、sampleRate 和 denyUrls。

VSCode 调试 Node 项目时,Sentry 默认抓不到未捕获异常(uncaughtException),必须显式启用 Sentry.init() 的 integrations 配置并确保初始化时机早于任何可能出错的代码。
Node 环境下 Sentry 不上报未捕获异常的典型表现
程序运行中突然退出,控制台打印 FATAL ERROR: ... uncaught exception 或 events.js:292 throw er; // Unhandled 'error' event,但 Sentry 后台查不到对应事件。这是因为 Sentry 的 Node SDK 默认只捕获显式调用 Sentry.captureException() 的错误,不自动监听全局未捕获异常——除非你主动开启对应集成。
-
process.on('uncaughtException')和process.on('unhandledRejection')是 Node 捕获崩溃的关键钩子,Sentry 的OnUncaughtException和OnUnhandledRejection集成就是基于它们实现的 - 若未启用这些集成,Sentry 就像“没装监听器”,即使异常炸了也收不到通知
- 常见误操作:只调用
Sentry.init({ dsn: '...' }),没传integrations,或把init()放在异步逻辑之后(比如app.listen()后)
必须在 require 后立即执行 Sentry.init()
Node 的模块加载是同步的,init() 必须在任何业务代码(尤其是可能抛错的 require、new Promise、fs.readFileSync 等)之前执行,否则错过早期异常。
- 推荐位置:入口文件(如
index.js或app.js)最顶部,紧随'use strict'之后 - 错误示例:
const app = require('./app'); Sentry.init(...)—— 此时./app里若含同步报错,Sentry 还没启动,就漏掉了 - 正确写法:
Sentry.init({ dsn: '...', integrations: [new Sentry.Integrations.OnUncaughtException(), new Sentry.Integrations.OnUnhandledRejection()] }); - 注意:Node SDK v7+ 已默认启用这两个集成,但旧版本(v6.x)仍需手动传入;建议显式声明,避免版本差异导致行为不一致
VSCode 调试时异常被吞掉?检查 launch.json 的 console 和 env
VSCode 的 Node 调试器默认会拦截未捕获异常并中断,这反而会让 Sentry 失去上报机会——因为异常没真正“冒泡”到 process 全局监听器。
- 在
.vscode/launch.json中添加"console": "integratedTerminal",让异常输出到终端而非调试面板,保证uncaughtException钩子能触发 - 必要时加
"env": { "NODE_OPTIONS": "--enable-source-maps" },确保堆栈包含原始行号(尤其用 TypeScript 或打包工具时) - 如果用了
nodemon或ts-node,确保runtimeExecutable指向正确可执行文件,并在args中传入--inspect参数 - 验证是否生效:故意在入口处写
throw new Error('test');,看 Sentry 是否收到事件,同时终端是否打印堆栈
本地探针调试要验证真实上报路径与采样率
开发时容易忽略 environment 和 sampleRate 导致本地异常看似没上报,其实是被过滤了。
- 务必设置
environment: 'development',避免和生产环境事件混在一起,也方便在 Sentry 控制台筛选 - 显式设
sampleRate: 1.0,禁用采样,确保每条异常都发出去(默认是 1.0,但某些配置覆盖后可能变 0) - 检查网络面板或终端日志:Sentry 发送请求时会打印
[Sentry] Sending error to Sentry,若没这句,说明根本没触发上报逻辑 - 注意:本地
localhost域名可能被 Sentry 的denyUrls规则拦截,可在 init 时加denyUrls: []清空黑名单
最容易被忽略的是初始化顺序和集成开关——不是“装了 Sentry 就自动管所有异常”,而是“你得亲手把它焊死在进程启动的第一毫秒”。一旦漏掉 OnUncaughtException 或晚调用 init(),本地调试时看到的崩溃就永远停留在终端里,进不了 Sentry 的时间线。


















