nodejs / nodejs/node

Missing import trace from error stack when loading a module throws an error

未关闭
#46,992 30 条评论 11 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

esm feature request
主要语言
JavaScript
星标
122k
派生
37.3k
平均合并
4 天 2 小时
30 天内合并 PR
283

描述

Version

v16.16.0

Platform

Linux 5.4.0-139-generic #156-Ubuntu SM x86_64 GNU/Linux

Subsystem

modules

What steps will reproduce the bug?

Consider:

// foo.mjs
import './bar.mjs';
// bar.mjs
throw new Error('bar failed');

Run node foo.mjs.

How often does it reproduce? Is there a required condition?

Always.

What is the expected behavior?

The stack trace from the error should include a reference to foo.mjs line 1 showing where bar was imported from.

What do you see instead?
file:///.../bar.mjs:1
throw new Error('bar failed');
      ^

Error: bar failed
    at file:///.../bar.mjs:1:7
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12)

Note that the stack trace does not mention foo anywhere. This is not helpful, especially if the error is specifically about how and when bar is imported. For example, it might be a singleton and you're mistakenly creating a duplicate by loading it from both import and require, or it might need something else to be set up on the global first and you're loading it in the wrong order.

The above stack is from node 16. Node 18 produces a shorter but similarly lacking stack:

file:///.../bar.mjs:1
throw new Error('bar failed');
      ^

Error: bar failed
    at file:///.../bar.mjs:1:7
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
Additional information

I am aware that import() and top-level await complicates this, since modules may be effectively loading in parallel (asynchronously behind the scenes). However, it is absolutely essential that this information is made available somehow.

If the output ends up being a list of all modules trying to load the offending module then great, as long as this list is in the order the imports were encountered then that should allow debugging this kind of thing.

At the moment when this occurs it's simply impossible to debug. Since import gets hoisted by the language you can't even add console.log statements around the place to trace what's happening like you can with require. Literally the only option to debug this is to comment out all the imports and re-enable one-by-one (recursively) until you locate the problem. And in practice this inevitably breaks something else, so it's completely unworkable.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先使用 node foo.mjs 通过 foo.mjs 和 bar.mjs 模块复现该问题,然后检查涉及 ESM 加载的模块子系统。跟踪错误如何通过模块导入和加载路径传播。完成的标准是所得的堆栈信息能够识别 foo.mjs 第 1 行,同时考虑所描述的异步导入情况。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript
领域
backend
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。