Skip to content

Incorrect error when aborted by AbortSignal.timeout(...) in jsdom #1477

Open
@Frederick888

Description

@Frederick888

Description

I have some code similar to the MDN example https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static#using_abortsignal.any that I'm trying to test with Jest and jsdom. Since jsdom doesn't offer its own fetch, I'm using this project to polyfill it.

However when a request is aborted due to AbortSignal.timeout(...), unlike browsers (Firefox) and Node.js (v22), it gives me an AbortError instead of TimeoutError.

Environment

  • Node.js v22.12.0
  • whatwg-fetch v3.6.20
  • Jest v29.7.0
  • jsdom v26.0.0
  • ts-jest v29.1.1

Steps to reproduce

Test code:

it('whatwg-fetch', async () => {
  try {
    const signal = AbortSignal.timeout(20)
    signal.addEventListener('abort', (ev) => {
      const currentTarget = ev.currentTarget as typeof ev.currentTarget & {
        reason: DOMException
      }
      console.debug({ reason: currentTarget.reason.name })
    })
    await fetch('https://example.com', { signal })
  } catch (e) {
    console.debug(e)
    expect((e as Error).name).toStrictEqual('TimeoutError')
  }
})

The test passes if I put

/**
 * @jest-environment node
 */

...at the top of the file. Output:

  console.debug  <-- log in signal.addEventListener
    { reason: 'TimeoutError' }

      at AbortSignal.<anonymous> (src/shared/hooks/http/fetch.test.ts:38:15)

  console.debug <-- log in catch
    DOMException [TimeoutError]: The operation was aborted due to timeout
        at node:internal/deps/undici/undici:13484:13

      at src/shared/hooks/http/fetch.test.ts:42:13
          at Generator.throw (<anonymous>)

 PASS  src/shared/hooks/http/fetch.test.ts (19.408 s)
  ✓ whatwg-fetch (501 ms)

The test fails if I put

/**
 * @jest-environment jsdom
 */
import 'whatwg-fetch'

...at the top of the file. Output:

  console.debug  <-- log in signal.addEventListener
    { reason: 'TimeoutError' }

      at AbortSignal.<anonymous> (src/shared/hooks/http/fetch.test.ts:38:15)

  console.debug <-- log in catch
    DOMException {}

      at src/shared/hooks/http/fetch.test.ts:42:13
          at Generator.throw (<anonymous>)

 FAIL  src/shared/hooks/http/fetch.test.ts (25.565 s)
  ✕ whatwg-fetch (412 ms)

  ● whatwg-fetch

    expect(received).toStrictEqual(expected) // deep equality

    Expected: "TimeoutError"
    Received: "AbortError"

      41 |   } catch (e) {
      42 |     console.debug(e)
    > 43 |     expect((e as Error).name).toStrictEqual('TimeoutError')
         |                               ^
      44 |   }
      45 | })
      46 |

      at src/shared/hooks/http/fetch.test.ts:43:31
          at Generator.throw (<anonymous>)
      at rejected (src/shared/hooks/http/fetch.test.ts:6:65)

And in Firefox, one can navigate to https://example.com, then in Console:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions