Implement AbortSignal.timeout()
Categories
(Core :: DOM: Core & HTML, enhancement)
Tracking
()
Tracking | Status | |
---|---|---|
firefox100 | --- | fixed |
People
(Reporter: d, Assigned: saschanaz)
References
(Blocks 1 open bug)
Details
(Keywords: dev-doc-complete)
Attachments
(3 files)
Spec PR/mini-explainer (landed): https://github.com/whatwg/dom/pull/1032
Spec: https://dom.spec.whatwg.org/#dom-abortsignal-timeout
Web platform tests PR (landed): https://github.com/web-platform-tests/wpt/pull/32622
Comment 1•1 year ago
|
||
![]() |
||
Comment 2•1 year ago
|
||
Landed on WebKit https://trac.webkit.org/changeset/289058/webkit
Comment 3•1 year ago
|
||
The implementation passes both https://wpt.live/dom/abort/AbortSignal.any.html and https://wpt.live/dom/abort/abort-signal-timeout.html. I am going to less active the next few weeks, so if this is urgent feel free to steal.
Comment 4•1 year ago
|
||
Bug 1734997 will probably use the timeout code too without any clamping.
Assignee | ||
Comment 5•1 year ago
|
||
Oh, I forgot to check this out. AFAICT the clamping can check TimeoutReason to not clamp for any new reasons.
Comment 6•1 year ago
|
||
sefeng is adding a flag to prevent clamping (for other reasons than this). Hopefully it can be reused.
Updated•1 year ago
|
Updated•1 year ago
|
Assignee | ||
Updated•1 year ago
|
Pushed by krosylight@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/53d1dd2040d5 Implement AbortSignal.timeout() r=smaug
Assignee | ||
Comment 8•1 year ago
|
||
Pushed by smolnar@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/c9ed1172b434 Fix build bustage CLOSED TREE
Assignee | ||
Comment 10•1 year ago
|
||
Comment 11•1 year ago
|
||
Pushed by smolnar@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/111699477b1f Fix build bustage 2 CLOSED TREE
Comment 12•1 year ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/53d1dd2040d5
https://hg.mozilla.org/mozilla-central/rev/c9ed1172b434
https://hg.mozilla.org/mozilla-central/rev/111699477b1f
Comment 13•1 year ago
|
||
FF100 docs work for this can be tracked in https://github.com/mdn/content/issues/14641
Looking at the explainer the "more full example" shows handling for both a timeout abort and an abort signal triggered explicitly. Further down the document it seems to indicate that this is not actually possible - you can either timeout the signal or abort it but not both. Is that correct?
Does that mean that if you want to do both you still need to do the suggestion in https://github.com/whatwg/fetch/issues/951 ? :
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 5000)
const res = await fetch('https://example.com', { signal: controller.signal })
const body = await res.json()
clearTimeout(timeoutId)
If not, what is the recommended way to handle this case?
Reporter | ||
Comment 14•1 year ago
|
||
shows handling for both a timeout abort and an abort signal triggered explicitly.
That is not what the example shows. As it says in the comments, the "AbortError" case is for cases like the user pressing the stop button, or the page navigating away, or...
Comment 15•1 year ago
•
|
||
shows handling for both a timeout abort and an abort signal triggered explicitly.
That is not what the example shows. As it says in the comments, the "AbortError" case is for cases like the user pressing the stop button, or the page navigating away, or...
**I understand that the example "shows" how you might catch the "AbortError" but I don't see how that can be triggered since you don't have the controller. Specifically, AbortSignal.timeout()
returns an AbortSignal
and there is no way to get hold of the AbortController so you can call abort on that signal (from the stop button).
Further down your comment appear support this case "requires future work", because otherwise why would you need fetch to take multiple signals?
To spell it out in excruciating detail, this is your example, which looks like it can catch a TimeoutError
, AbortError
or something else. The fetch only takes the signal returned by AbortSignal.timeout()
. How would the code get a handle to the controller in order call abort on this?
try {
const res = await fetch(url, { signal: AbortSignal.timeout(10_000) });
const result = await res.text();
// ...
} catch (e) {
if (e.name === "TimeoutError") {
// It took more than 10 seconds to get the result!
} else if (e.name === "AbortError") {
// The fetch was explicitly aborted, e.g. by the user pressing the stop button!
} else {
// Something horrible went wrong, like a network error!
}
}
And then you say.
Future work: this feature would benefit greatly from a solution for combining AbortSignals, so that people could have an operation that aborts on either a timeout or an explicit abort. For example, something like this:
// NOT REAL CODE, YET: const controller = new AbortController(); fetch(url, { signal: AbortSignal.all([AbortSignal.timeout(10_000), controller.signal]) }); abortButton.onclick = () => controller.abort();
I hope this has explained my confusion enough that you can explain where I'm completely missing the point?
Reporter | ||
Comment 16•1 year ago
|
||
I understand that the example "shows" how you might catch the "AbortError" but I don't see how that can be triggered since you don't have the controller.
It can be triggered by the user pressing the stop button on their browser, which will cancel the fetch. The controller is not involved.
Comment 17•1 year ago
|
||
Thanks very much, it did not occur to me that browser chrome might also stop a download. I've updated the docs to reflect this.
Description
•