VSCode插件调试时收不到uncaughtException是因为Extension Host调试器默认拦截未捕获异常,不触发process全局钩子;必须在extension.ts顶部同步调用Sentry.init()并配置OnUncaughtException、OnUnhandledRejection集成,且launch.json中console设为integratedTerminal。

VSCode插件调试时为什么收不到 uncaughtException
因为 VSCode 的 Extension Host 调试器默认不把未捕获异常透传给 Node.js 全局钩子,process.on('uncaughtException') 和 process.on('unhandledRejection') 在插件进程里形同虚设——不是你没写,而是调试环境主动拦截并吞掉了。
必须在 extension.ts 最顶部同步调用 Sentry.init()
哪怕只差一行,就可能漏掉入口文件里 require 或 import 引发的同步崩溃。常见错误包括:
-
Sentry.init()写在activate()函数里——此时插件已开始注册命令、监听事件,早期异常早已发生 - 先
import * as vscode from 'vscode',再初始化 Sentry——但某些插件依赖的模块(如vscode-languageclient)内部可能含同步报错 - 没显式传
integrations,尤其在旧版 SDK(v6.x)中,OnUncaughtException和OnUnhandledRejection默认关闭
正确写法(紧贴文件开头):
import * as Sentry from '@sentry/node';
<p>Sentry.init({
dsn: '<a href="https://www.php.cn/link/68624a8a1f8dd04e260c0173bad7ee31">https://www.php.cn/link/68624a8a1f8dd04e260c0173bad7ee31</a>',
integrations: [
new Sentry.Integrations.OnUncaughtException(),
new Sentry.Integrations.OnUnhandledRejection(),
],
// 确保不被插件市场或用户环境过滤
denyUrls: [/^file:\/\//, /^chrome:\/\//],
});
launch.json 的 console 必须设为 integratedTerminal
这是最常被忽略的配置项。若 console 是 externalTerminal 或 internalConsole,Sentry 的异常上报逻辑会因标准输出重定向失败而静默丢弃。
-
console: "integratedTerminal"才能保证process.stderr.write正常触发,Sentry 才有机会序列化并发送事件 - 同时确认
env中透传了必要变量,比如某些 SDK 需要NODE_OPTIONS: "--trace-warnings"来暴露隐式拒绝 - 别信
exceptions字段:VSCode Node 调试器完全忽略launch.json里的"exceptions": { "uncaught": true },它只响应 UI 断点面板里的开关
Promise 拒绝必须手动启用 Uncaught Promise Rejections 断点
插件里大量异步操作(如 vscode.workspace.findFiles()、fetch() 封装)一旦没加 .catch() 或 try/catch await,就会触发 unhandledRejection——但 VSCode 默认不中断,也不上报 Sentry,除非你肉眼盯住「运行和调试」侧边栏的断点区域:
- 点击「断点」区域右上角的
+号 → 选择Node.js: Uncaught Promise Rejections - 确保该条目是实心勾选状态(灰色空心 = 未启用)
- 这个开关和
Uncaught Exceptions是两个独立开关,少一个,Promise 崩溃就无声无息 - F5 启动调试才生效;终端里直接
node ./extension.js不走这套机制
真正难调试的,永远不是你看见的报错,而是那些连堆栈都没留下、进程直接退出的瞬间——它们往往发生在插件加载初期,且只在用户机器上复现。盯住 integratedTerminal 输出和 Sentry 的 denyUrls 配置,比加一百个 console.log 更管用。


















