如何在Node.js ES模块中显示有效的错误回溯信息?
Node.js ES模块错误回溯显示问题的解决方法
问题重现
测试代码(分别保存为a.cjs和a.mjs):
console.log("hi") throw "err"
运行命令:
node --trace-uncaught a.cjs node --trace-uncaught a.mjs
CommonJS版本能正确显示错误抛出位置,但ES模块版本的错误回溯仅指向内部加载器,无法定位到用户代码的错误行。
解决方法
1. 封装顶层代码到函数中执行
将顶层直接抛出错误的逻辑包裹在函数内调用,让错误在用户代码的调用栈中抛出,避免被ES模块加载器逻辑掩盖:
console.log("hi"); function run() { throw "err"; } run();
再次运行node --trace-uncaught a.mjs,错误回溯会正确显示:
hi file:///home/kkocdko/misc/code/kblog/a.mjs:3:3 throw "err"; ^ err Thrown at: at run (file:///home/kkocdko/misc/code/kblog/a.mjs:3:3) at file:///home/kkocdko/misc/code/kblog/a.mjs:5:1 at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
2. 升级Node.js到v18及以上版本
Node.js在v18.x的后续稳定版本中修复了ES模块顶层错误栈丢失的问题,升级后直接运行原始的a.mjs代码,就能看到完整的错误回溯:
hi file:///home/kkocdko/misc/code/kblog/a.mjs:2 throw "err" ^ err Thrown at: at file:///home/kkocdko/misc/code/kblog/a.mjs:2:1 at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
原因说明
旧版本Node.js中,ES模块的顶层代码执行流程与CommonJS不同,顶层抛出的错误会经过内部ES模块加载器的封装处理,导致原始错误位置被加载器的调用栈覆盖。通过封装代码到函数中,错误会在用户自定义的调用栈中触发,从而保留正确的位置信息;新版本Node.js优化了ES模块的错误追踪逻辑,直接保留了顶层代码的错误位置。
内容的提问来源于stack exchange,提问作者kkocdko
相关产品推荐
相关产品推荐

