Node.js Express项目调用Sentry.captureException提示undefined
问题排查及解决方案
1. 优先排查循环依赖问题
这是这类导出undefined最常见的诱因:
- 若你导入Sentry的文件,同时被初始化Sentry的主文件依赖(比如主文件引入了这个文件里的路由、中间件),就会出现模块循环加载。NodeJS处理循环依赖时会返回未完成的模块导出对象,此时你解构拿到的Sentry就是undefined。
- 排查方法:
在主文件的module.exports代码前加一行打印:console.log('主文件导出Sentry', Sentry)
在导入Sentry的文件中,require后立刻打印完整导出对象:
如果导入文件的打印先于主文件导出的打印,就可以确定是循环依赖问题。const allExports = require('./path/to/above/file') console.log('拿到的导出内容', allExports) const { Sentry } = allExports - 解决方案:把Sentry初始化逻辑单独抽离为独立文件,比如
sentry.config.js:
之后主文件和需要上报错误的文件,都直接引入这个独立文件即可,彻底规避循环依赖。const Sentry = require('@sentry/node'); const Tracing = require('@sentry/tracing'); Sentry.init({ dsn: '...', integrations: [ new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express(), ], tracesSampleRate: 0.8, }); module.exports = Sentry
2. 检查导入路径是否正确
相对路径很容易出现层级错误,比如少写层级、拼写错误:
- 确认你写的
./path/to/above/file是从当前文件到Sentry初始化文件的正确相对路径,若当前文件在子目录下,需要用../返回上级目录。 - 要是打印上面提到的
allExports是空对象,基本可以确定是路径写错了。
3. 检查导出代码位置是否正确
确认module.exports是写在主文件的顶层同步代码中,不要包裹在server.listen回调、异步函数、条件判断等代码块内,否则模块同步加载完成时还没有执行导出逻辑,拿到的就是空导出对象。
4. 临时替代方案
Sentry本身是单例模式,只要你在主文件已经执行过Sentry.init初始化,其他需要上报错误的文件可以直接引入sentry/node包,不需要从主文件中转导出:
const Sentry = require('@sentry/node') // 直接调用即可,配置已经在主文件初始化完成 Sentry.captureException(ex)
内容的提问来源于stack exchange,提问作者Alk
相关产品推荐
相关产品推荐

