Skip to content

Abort timed-out requests with TimeoutError DOMException#41

Merged
snoack merged 1 commit into
masterfrom
abort-signal-timeout
May 7, 2026
Merged

Abort timed-out requests with TimeoutError DOMException#41
snoack merged 1 commit into
masterfrom
abort-signal-timeout

Conversation

@snoack
Copy link
Copy Markdown
Contributor

@snoack snoack commented May 6, 2026

This mimics the intrinsic behavior of AbortSignal.timeout() which we plan to eventually switch to.

This change is Reviewable

@pkaminski
Copy link
Copy Markdown
Member

@codex review

Triggered automatically because this PR was opened ready for review or was marked ready for review.

@snoack snoack force-pushed the abort-signal-timeout branch from 30435e2 to 737af34 Compare May 6, 2026 17:28
@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

if (config.timeout) init.signal = AbortSignal.timeout(config.timeout);

P2 Badge Preserve timeout fallback for older browser runtimes

Using AbortSignal.timeout() unconditionally regresses browser compatibility for clients that support fetch/AbortController but not the newer static timeout API; in those environments, any request with timeout set now throws TypeError: AbortSignal.timeout is not a function before the network call starts. The previous AbortController + setTimeout path worked there, so this change breaks timeout-enabled requests unless you add a feature-detected fallback.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor Author

@snoack snoack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not bump the version yet, because as far as I'm concerned it's fine if this simplification makes it into the next release. However, if you want to do another release before we update the dependency in Reviewable, let me know.

Using AbortSignal.timeout() unconditionally regresses browser compatibility

AbortSignal.timeout requires Chrome 103, Firefox 100 or Safari 15.4 — which are all from early 2022 and well past the "last 2 versions" cutoff.

@snoack made 1 comment.
Reviewable status: 0 of 3 files reviewed, all discussions resolved.

@snoack snoack requested a review from pkaminski May 6, 2026 17:42
Copy link
Copy Markdown
Member

@pkaminski pkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please always bump the version as it's not possible to overwrite a previously published version with new code.

caniuse says it's more like a 2024 baseline and 88% penetration. I usually accept that for features with minor side-effects (e.g., degraded visuals or a very specific action failing) but for whole-app-breaking stuff I prefer to set the bar at 93% or so unless it makes our life significantly easier. The "last 2 versions" cutoff is mostly for CSS.

@pkaminski reviewed 3 files and all commit messages, and made 2 comments.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on snoack).


README.md line 131 at r2 (raw file):

* `host`: The URL to prepend to all request paths; defaults to `https://api.github.com`.
* `graphHost`: The URL to use for all GraphQL requests; defaults to using the value of `host` which works fine for `github.com`, but you'll need to set a separate value when working with GitHub Enterprise.
* `timeout`: The timeout in milliseconds to apply to the request; none by default.  If the timeout is reached, the request will abort with a `TimeoutError`.

I guess that's technically another major version bump.

Copy link
Copy Markdown
Contributor Author

@snoack snoack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex did lied to me. The browser versions stated above are wrong, instead it requires Chrome 124 which was released in 2024. Fair enough, I'm closing this PR.

@snoack made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on snoack).

@snoack snoack closed this May 6, 2026
@snoack snoack reopened this May 6, 2026
@snoack snoack changed the title Use AbortSignal.timeout() instead of AbortController + setTimeout Use AbortSignal.timeout() if available instead of AbortController + setTimeout May 6, 2026
@snoack snoack force-pushed the abort-signal-timeout branch from 737af34 to 7124b6b Compare May 6, 2026 21:33
@snoack snoack requested a review from pkaminski May 6, 2026 21:42
Copy link
Copy Markdown
Contributor Author

@snoack snoack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reopened the PR, and made the change backwards compatible. What do you think?

@snoack made 2 comments.
Reviewable status: 1 of 4 files reviewed, 1 unresolved discussion (waiting on pkaminski).


README.md line 131 at r2 (raw file):

Previously, pkaminski (Piotr Kaminski) wrote…

I guess that's technically another major version bump.

Do you think it would be acceptable to only bump the minor version here? I don't want to run through major versions unnecessarily fast, and if we release this soon, 7.0.0 was only briefly available and never used by Reviewable.

Copy link
Copy Markdown
Member

@pkaminski pkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced it's worth it: it increases code complexity and introduces a noticeable discrepancy between real TimeoutError instances and AbortError instances with a name override that will fail an instanceof test. I'd just wait a year or two and migrate to AbortSignal.timeout wholesale once it's supported well enough..

@pkaminski reviewed 2 files and all commit messages, made 2 comments, and resolved 1 discussion.
Reviewable status: 3 of 4 files reviewed, all discussions resolved (waiting on snoack).


README.md line 131 at r2 (raw file):

Previously, snoack (Sebastian Noack) wrote…

Do you think it would be acceptable to only bump the minor version here? I don't want to run through major versions unnecessarily fast, and if we release this soon, 7.0.0 was only briefly available and never used by Reviewable.

Yeah, I think it'd be fine to make an exception in this case.

@snoack snoack requested a review from pkaminski May 7, 2026 00:30
Copy link
Copy Markdown
Contributor Author

@snoack snoack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could throw new DOMException('The operation timed out.', 'TimeoutError') to 100% match the original exception. One benefit of using AbortSignal.timeout in Node.js is that unlikesetTimeout it doesn't keep the process alive, also it is lightweighter. But the complexity of having two different code paths is a valid counter point.

@snoack made 1 comment.
Reviewable status: 3 of 4 files reviewed, all discussions resolved (waiting on pkaminski).

Copy link
Copy Markdown
Member

@pkaminski pkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I thought that TimeoutError was a separate class — my mistake. I don't think setTimeout keeping the process alive is an issue since we use System.exit consistently instead of relying on self-termination.

How about this: let's stick with AbortController to retain a single code path but faithfully emulate TimeoutError when throwing. That way, all the clients can be migrate to the future API right away, and when the time comes to switch to AbortSignal we'll be able to do so easily. What do you think?

@pkaminski made 1 comment.
Reviewable status: 3 of 4 files reviewed, all discussions resolved (waiting on snoack).

@snoack snoack changed the title Use AbortSignal.timeout() if available instead of AbortController + setTimeout Abort timed-out requests with TimeoutError DOMException May 7, 2026
@snoack snoack force-pushed the abort-signal-timeout branch from 7124b6b to bc625bc Compare May 7, 2026 17:46
@snoack snoack requested a review from pkaminski May 7, 2026 17:46
Copy link
Copy Markdown
Contributor Author

@snoack snoack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@snoack made 1 comment.
Reviewable status: 3 of 4 files reviewed, all discussions resolved (waiting on pkaminski).

This mimics the intrinsic behavior of AbortSignal.timeout() which we plan to eventually switch to.
@snoack snoack force-pushed the abort-signal-timeout branch from bc625bc to a79ca0e Compare May 7, 2026 17:51
Copy link
Copy Markdown
Member

@pkaminski pkaminski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pkaminski reviewed 2 files and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on snoack).

@snoack snoack merged commit 47b0cb8 into master May 7, 2026
4 checks passed
@snoack snoack deleted the abort-signal-timeout branch May 7, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants