Skip to content

Commit c0ec08a

Browse files
authored
feat(browser): add trackUnhandledErrors option (#8386)
1 parent 28b5e09 commit c0ec08a

File tree

11 files changed

+56
-3
lines changed

11 files changed

+56
-3
lines changed

docs/guide/browser/config.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,17 @@ The timeout in milliseconds. If connection to the browser takes longer, the test
326326
This is the time it should take for the browser to establish the WebSocket connection with the Vitest server. In normal circumstances, this timeout should never be reached.
327327
:::
328328

329+
## browser.trackUnhandledErrors
330+
331+
- **Type:** `boolean`
332+
- **Default:** `true`
333+
334+
Enables tracking uncaught errors and exceptions so they can be reported by Vitest.
335+
336+
If you need to hide certain errors, it is recommended to use [`onUnhandledError`](/config/#onunhandlederror) option instead.
337+
338+
Disabling this will completely remove all Vitest error handlers, which can help debugging with the "Pause on exceptions" checkbox turned on.
339+
329340
## browser.expect
330341

331342
- **Type:** `ExpectOptions`

docs/guide/cli-generated.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,13 @@ Should browser test files run in parallel. Use `--browser.fileParallelism=false`
376376

377377
If connection to the browser takes longer, the test suite will fail (default: `60_000`)
378378

379+
### browser.trackUnhandledErrors
380+
381+
- **CLI:** `--browser.trackUnhandledErrors`
382+
- **Config:** [browser.trackUnhandledErrors](/guide/browser/config#browser-trackunhandlederrors)
383+
384+
Control if Vitest catches uncaught exceptions so they can be reported (default: `true`)
385+
379386
### pool
380387

381388
- **CLI:** `--pool <pool>`

packages/browser/src/client/public/error-catcher.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@ function catchWindowErrors(errorEvent, prop, cb) {
5555
}
5656

5757
function registerUnexpectedErrors() {
58-
catchWindowErrors('error', 'error', event =>
58+
const offError = catchWindowErrors('error', 'error', event =>
5959
reportUnexpectedError('Error', event.error))
60-
catchWindowErrors('unhandledrejection', 'reason', event =>
60+
const offRejection = catchWindowErrors('unhandledrejection', 'reason', event =>
6161
reportUnexpectedError('Unhandled Rejection', event.reason))
62+
return () => {
63+
offError()
64+
offRejection()
65+
}
6266
}
6367

6468
async function reportUnexpectedError(
@@ -71,4 +75,4 @@ async function reportUnexpectedError(
7175
}).catch(console.error)
7276
}
7377

74-
registerUnexpectedErrors()
78+
globalThis.__vitest_browser_runner__.disposeExceptionTracker = registerUnexpectedErrors()

packages/browser/src/client/public/esm-client-injector.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
window.__vitest_browser_runner__ = {
2020
wrapModule,
2121
wrapDynamicImport: wrapModule,
22+
disposeExceptionTracker: () => {},
2223
moduleCache,
2324
cleanups: [],
2425
config: { __VITEST_CONFIG__ },

packages/browser/src/client/tester/tester.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ async function prepare(options: PrepareOptions) {
217217
})
218218
})(),
219219
])
220+
221+
if (!config.browser.trackUnhandledErrors) {
222+
getBrowserState().disposeExceptionTracker()
223+
}
220224
}
221225

222226
async function cleanup() {

packages/browser/src/client/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export interface BrowserRunnerState {
7575
}
7676
providedContext: string
7777
type: 'tester' | 'orchestrator'
78+
disposeExceptionTracker: () => void
7879
wrapModule: <T>(module: () => T) => T
7980
iframeId?: string
8081
sessionId: string

packages/vitest/src/node/cli/cli-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ export const cliOptionsConfig: VitestCLIOptions = {
411411
description: 'If connection to the browser takes longer, the test suite will fail (default: `60_000`)',
412412
argument: '<timeout>',
413413
},
414+
trackUnhandledErrors: {
415+
description: 'Control if Vitest catches uncaught exceptions so they can be reported (default: `true`)',
416+
},
414417
orchestratorScripts: null,
415418
testerScripts: null,
416419
commands: null,

packages/vitest/src/node/config/serializeConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ export function serializeConfig(
156156
actionTimeout: (browser.providerOptions as any)?.context?.actionTimeout,
157157
}
158158
: {},
159+
trackUnhandledErrors: browser.trackUnhandledErrors ?? true,
159160
}
160161
})(config.browser),
161162
standalone: config.standalone,

packages/vitest/src/node/types/browser.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,16 @@ export interface BrowserConfigOptions {
248248
}
249249
}[keyof ToMatchScreenshotComparators] & ToMatchScreenshotOptions
250250
}
251+
252+
/**
253+
* Enables tracking uncaught errors and exceptions so they can be reported by Vitest.
254+
*
255+
* If you need to hide certain errors, it is recommended to use [`onUnhandledError`](https://vitest.dev/config/#onunhandlederror) option instead.
256+
*
257+
* Disabling this will completely remove all Vitest error handlers, which can help debugging with the "Pause on exceptions" checkbox turned on.
258+
* @default true
259+
*/
260+
trackUnhandledErrors?: boolean
251261
}
252262

253263
export interface BrowserCommandContext {

packages/vitest/src/runtime/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export interface SerializedConfig {
122122
// for playwright
123123
actionTimeout?: number
124124
}
125+
trackUnhandledErrors: boolean
125126
}
126127
standalone: boolean
127128
logHeapUsage: boolean | undefined

0 commit comments

Comments
 (0)