Skip to content

Request object's AbortSignal does not abort with the expected reason #43874

Closed
nodejs/undici
#1580
@cambecc

Description

Version

v18.5.0

Platform

Linux foo 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

const signal1 = AbortSignal.timeout(100);
const request = new Request("https://example.com", {signal: signal1});
const signal2 = request.signal;

console.log("same?", signal1 === signal2);  // false

signal1.addEventListener("abort", e => console.log("1", e.target.reason));  // TimeoutError
signal2.addEventListener("abort", e => console.log("2", e.target.reason));  // AbortError

setTimeout(() => {}, 200);  // wait for the abort to happen

How often does it reproduce? Is there a required condition?

Always.

What is the expected behavior?

The Request's signal should abort with the same reason as the signal provided during Request construction. (In this case, a TimeoutError.)

What do you see instead?

The Request's signal aborts with a different reason from the signal provided during construction. In this repro, the TimeoutError is converted to AbortError, which is a loss of information.

same? false
2 DOMException [AbortError]: This operation was aborted
    at new DOMException (node:internal/per_context/domexception:53:5)
    at AbortController.abort (node:internal/abort_controller:320:18)
    at AbortSignal.abort (node:internal/deps/undici/undici:4974:36)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:645:20)
    at AbortSignal.dispatchEvent (node:internal/event_target:587:26)
    at abortSignal (node:internal/abort_controller:292:10)
    at Timeout._onTimeout (node:internal/abort_controller:112:7)
    at listOnTimeout (node:internal/timers:564:17)
    at process.processTimers (node:internal/timers:507:7)
1 DOMException [TimeoutError]: The operation was aborted due to timeout
    at new DOMException (node:internal/per_context/domexception:53:5)
    at Timeout._onTimeout (node:internal/abort_controller:114:9)
    at listOnTimeout (node:internal/timers:564:17)
    at process.processTimers (node:internal/timers:507:7)

FWIW, recent versions of both Chrome and Firefox perform as expected (TimeoutError seen by both event handlers).

Additional information

It seems the signal provided during Request construction is wrapped by a new abort controller/signal (see the output: "same? false"). Is the reason of the underlying signal passed to the new controller's abort() call? Looks like no.

Metadata

Assignees

No one assigned

    Labels

    abortcontrollerIssues and PRs related to the AbortController APIfetchIssues and PRs related to the Fetch API

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions