Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhelpful error.stack in browser mode #7370

Open
6 tasks done
diego-aquino opened this issue Jan 28, 2025 · 3 comments
Open
6 tasks done

Unhelpful error.stack in browser mode #7370

diego-aquino opened this issue Jan 28, 2025 · 3 comments
Labels
feat: browser Issues and PRs related to the browser runner p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@diego-aquino
Copy link

Describe the bug

In browser mode, error.stack is not pointing to the correct line and column where the error was declared.

For example, the following code

it('should have a correct stack trace in browser mode', () => {
  const error = new Error();
  console.log(error.stack);
});

outputs

Error
    at http://localhost:63315/home/diegoaquino/www/vitest-issues/vitest-browser-error-stack/example.test.ts?import&browserv=1738024191536:3:17
    at http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:174:14
    at http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:561:28
    at http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:61:24
    at new Promise (<anonymous>)
    at runWithTimeout (http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:41:12)
    at runTest (http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:1140:17)
    at async runSuite (http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:1294:15)
    at async runFiles (http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:1351:5)
    at async startTests (http://localhost:63315/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js?v=4738659e:1361:3)

Notice how each line starts with http:// and points to the built file. Trying to open the first link in a browser is unsuccessful:

http://localhost:63315/home/diegoaquino/www/vitest-issues/vitest-browser-error-stack/example.test.ts?import&browserv=1738024191536:3:17

Image

Also, the line and column numbers (3:17) are incorrect. Maybe the source map is not being considered?


Compared to other tracing alternatives, console.trace() appears to work fine, even though the stack trace is not as complete as when browser mode is disabled:

it('should have a correct `console.trace` output in browser mode', () => {
  console.trace('Trace');
});

outputs

Trace
    at /home/diegoaquino/www/vitest-issues/vitest-browser-error-stack/example.test.ts:7:10

I frequently rely on stack traces for debugging. It would be really useful if error.stack pointed to the correct line and column in browser mode. This problem does not occur when it is disabled (e.g. environment: 'node').

Please let me know if this is a configuration issue on my part!

Reproduction

https://github.com/diego-aquino/vitest-browser-error-stack

System Info

System:
    OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
    CPU: (12) x64 Intel(R) Core(TM) i5-10400F CPU @ 2.90GHz
    Memory: 8.63 GB / 15.54 GB
    Container: Yes
    Shell: 5.8.1 - /usr/bin/zsh
  Binaries:
    Node: 22.13.1 - /usr/bin/node
    npm: 10.9.2 - ~/.n/bin/npm
    pnpm: 9.12.3 - ~/.n/bin/pnpm
    bun: 1.1.27 - ~/.bun/bin/bun
  Browsers:
    Chrome: 132.0.6834.110
  npmPackages:
    @vitest/browser: ^3.0.4 => 3.0.4 
    vitest: ^3.0.4 => 3.0.4

Used Package Manager

pnpm

Validations

@hi-ogawa
Copy link
Contributor

I don't think console.trace is working well either even though we manipulate stack trace for this case:

console.trace = (...args: unknown[]) => {
trace(...args)
const content = processLog(args)
const error = new Error('$$Trace')
const processor = (globalThis as any).__vitest_worker__?.onFilterStackTrace || ((s: string) => s || '')
const stack = processor(error.stack || '')
sendLog('stderr', `${content}\n${stack}`, true)
}

For example, when console.trace comes from non test files, this is what I see:

// example.test.ts
import { it } from 'vitest';
import { testTrace } from "./example";

it("repro", () => {
  testTrace();
})

// example.ts
export type Dummy = {
}

export function testTrace() {
  testTraceInner();
}

function testTraceInner() {
  console.trace("repro")
}
stderr | example.test.ts > repro
repro
    at testTraceInner(/example.ts:5:11)   <-- ❌
    at testTrace(/example.ts:2:3) <-- ❌
    at /home/hiroshi/code/tmp/vitest-browser-error-stack/example.test.ts:5:2  <-- 🆗

We'll probably need to obtain all source files in BrowserTestRunner.sourceMapCache to make it complete.


Then back to console.log(error.stack), supporting trace rewriting for arbitrary console.log(<any string>) is probably not possible, but it might be reasonable to support the error instance console.log(error) and rewrite error.stack on Vitest side automatically.

@hi-ogawa hi-ogawa added p3-minor-bug An edge case that only affects very specific usage (priority) feat: browser Issues and PRs related to the browser runner and removed pending triage labels Jan 28, 2025
@diego-aquino
Copy link
Author

diego-aquino commented Jan 28, 2025

Then back to console.log(error.stack), supporting trace rewriting for arbitrary console.log() is probably not possible, but it might be reasonable to support the error instance console.log(error) and rewrite error.stack on Vitest side automatically.

@hi-ogawa, is it possible to somehow rewrite error.stack to point to the right spot when the error is created?

A common way I use to get the current stack is by using error.stack:

function getCurrentStack(): string {
  return new Error().stack;
}

This currently only works outside of browser mode.

@hi-ogawa
Copy link
Contributor

is it possible to somehow rewrite error.stack to point to the right spot when the error is created?

It would require guessing stack trace by parsing any string passed from console.log(<any string>) and that's not something we might want to do (though I think browser devtools might be actually doing such guessing/parsing as they somehow rewrite raw string in some cases).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: browser Issues and PRs related to the browser runner p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
None yet
Development

No branches or pull requests

2 participants