Skip to content

expect.toThrow doesn't work correctly if actual is an error from another realm #8898

@al3xnag

Description

@al3xnag

Describe the bug

If function throws an error which is instance of another realm, expect.toThrow will pass with any expected error instance.

With the given setup:

import vm from 'node:vm'
const script = new vm.Script('fn = () => { throw new TypeError("oops") }')
const context = {}
vm.createContext(context)
script.runInContext(context)
const { fn } = context

all of the following assertions will pass at the same time (!):

expect(fn).toThrow(new TypeError('oops'))
expect(fn).toThrow(new TypeError('message'))
expect(fn).toThrow(new ReferenceError('oops'))
expect(fn).toThrow(new EvalError('no way'))

Reproduction

Unfortunately, repro on https://stackblitz.com doesn't reproduce this problem. I think it has to do with the way StackBlitz works (WebContainers) - new vm.Script().runInContext() doesn't actually give us cross-realm global instances (Object, Array, TypeError, etc.) in StackBlitz.

So, to reproduce this, you need to download this StackBlitz repro project and try it locally.

System Info

System:
    OS: macOS 26.0.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 1.97 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.21.0 - /opt/homebrew/opt/node@22/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.9.4 - /opt/homebrew/opt/node@22/bin/npm
    pnpm: 9.9.0 - /Users/al3x/Library/pnpm/pnpm
    bun: 1.2.2 - /Users/al3x/.bun/bin/bun
    Deno: 1.46.1 - /Users/al3x/.deno/bin/deno
  Browsers:
    Chrome: 141.0.7390.123
    Firefox: 139.0.4
    Firefox Developer Edition: 130.0
    Firefox Nightly: 131.0a1
    Safari: 26.0.1

Used Package Manager

npm

Validations

Metadata

Metadata

Assignees

Labels

p2-edge-caseBug, but has workaround or limited in scope (priority)

Type

Projects

Status

Has plan

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions