Skip to content

fix(cli): report eval scripts as [eval] URL for inspector#34192

Merged
littledivy merged 1 commit into
mainfrom
orch/divybot-124
May 17, 2026
Merged

fix(cli): report eval scripts as [eval] URL for inspector#34192
littledivy merged 1 commit into
mainfrom
orch/divybot-124

Conversation

@divybot
Copy link
Copy Markdown
Contributor

@divybot divybot commented May 17, 2026

Summary

Match Node.js by reporting -e and deno eval scripts as [eval] in inspector messages — Debugger.scriptParsed, Debugger.paused locations, and stack traces produced by vm.runInThisContext. Previously Deno reported the synthetic file:///…/$deno$eval.mts resource name (and evalmachine.<anonymous> for the user code inside the Node-compat wrapper), so any Node test that checks the script URL after attaching the inspector would fail.

Two small changes:

  1. eval_command appends //# sourceURL=[eval] to the eval source so V8 reports the eval main module URL as [eval]. Appended (not prepended) so user line numbers are preserved.
  2. wrap_eval_code (used when Node-style -e is translated for child processes via op_node_translate_cli_args) passes { filename: "[eval]" } to vm.runInThisContext so the wrapped user code is also reported with the [eval] URL.

Enables parallel/test-inspector-async-stack-traces-promise-then.js in node compat.

What's not in this PR

The two timer tests referenced in the original issue
(test-inspector-async-stack-traces-set-interval.js and
test-inspector-async-hook-setup-at-inspect-brk.js) need pieces that
don't exist yet and weren't appropriate to land here:

  • V8Inspector::asyncTaskScheduled / asyncTaskStarted / asyncTaskFinished bindings. Required so setTimeout / setInterval populate the asyncStackTrace field on Debugger.paused. V8 handles this automatically for promises via SetAsyncEventDelegate, but timers must call the hooks themselves. The v8 crate doesn't expose these methods today — they need to be added in denoland/rusty_v8 first.
  • node:internal/process/execution frame on the async parent. Both timer tests .some() over asyncStackTrace.callFrames looking for a frame with frame.url === 'node:internal/process/execution'. In Node this comes from evalScript, which lives in that internal module; Deno has no equivalent module today.
  • breakOnFirstLine semantics. test-inspector-async-hook-setup-at-inspect-brk.js expects the first --inspect-brk pause to be at line 1 of the user code, not at the wrapper's first statement. Node achieves this by passing breakOnFirstLine to vm.Script::Compile; V8 exposes the option but it's not on the Rust binding either.

I left those tests commented out in tests/node_compat/config.jsonc for follow-up.

Test plan

  • cargo test --test node_compat -- test-inspector-async-stack-traces-promise-then → passes
  • Confirm [eval] URL appears in Debugger.scriptParsed for both deno eval and spawn-translated -e paths
  • deno eval 'throw new Error()' stack trace unchanged (V8 stack uses ScriptOrigin name, not sourceURL)
  • cargo test --test node_compat -- test-inspector-promises test-inspector-strip-types test-inspector-resource-name-to-url test-inspector-emit-protocol-event test-inspector-break-e test-inspector-multisession-ws → no regression
  • cargo clippy --bin deno

Closes denoland/orchid#124

Match Node.js by reporting `-e` and `deno eval` scripts as `[eval]` in
inspector messages (Debugger.scriptParsed, Debugger.paused locations,
stack traces produced by `vm.runInThisContext`).

This unblocks `parallel/test-inspector-async-stack-traces-promise-then.js`
in node compat, which checks the script URL via `Debugger.paused`.

Two changes:

1. `eval_command` appends `//# sourceURL=[eval]` to the eval source so V8
   reports the eval main module URL as `[eval]` (it falls back to the
   `$deno$eval.mts` resource name otherwise). Appended (not prepended) so
   user line numbers are preserved.

2. `wrap_eval_code` (used when Node-style `-e` is translated for child
   processes via `op_node_translate_cli_args`) passes
   `{ filename: "[eval]" }` to `vm.runInThisContext` so the wrapped user
   code is also reported with the `[eval]` URL.

The remaining two failing tests
(`test-inspector-async-stack-traces-set-interval.js` and
`test-inspector-async-hook-setup-at-inspect-brk.js`) need additional
infrastructure that isn't covered here: V8 inspector
`asyncTaskScheduled` / `asyncTaskStarted` / `asyncTaskFinished` bindings
(not exposed by the `v8` crate today) wired through Deno's timer
plumbing, a `node:internal/process/execution` URL on the wrapper's
frames, and `breakOnFirstLine` semantics so `--inspect-brk` pauses
inside the user code rather than at the wrapper.

Closes denoland/orchid#124

Co-Authored-By: Divy Srivastava <me@littledivy.com>
@littledivy littledivy merged commit 01e228d into main May 17, 2026
136 checks passed
@littledivy littledivy deleted the orch/divybot-124 branch May 17, 2026 15:12
bartlomieju added a commit that referenced this pull request May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants