nodejs / nodejs/node

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

オープン
#46,992 コメント 30 件 リアクション 11 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

esm feature request
主要言語
JavaScript
スター
122k
フォーク
37.3k
平均マージ
4日 2時間
マージ済み PR(30日)
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. リポジトリをフォークし、ブランチを切って変更します。
  4. 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 を短くまとめたダイジェスト。