-
Notifications
You must be signed in to change notification settings - Fork 295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encourage use of AbortError for cancellation? #927
Comments
@domenic might have thoughts given whatwg/webidl#933 (comment). |
I think Domenic's (also interesting) suggestion is the inverse of this one. Jake is suggesting a way for signals to "throw if cancelled" and Domenic is suggesting a way for consumers to filter out cancellations as not exceptional in cases. Both seem useful to me in their own right. Worth mentioning that for Node it would be more convenient if the method Domenic is proposing was on |
I meant the part where @domenic doesn't necessarily want to couple |
I think coupling them is fine overall. My comment there was more about layering. That proposal has to do with exceptions, not Abort signals, i.e. ignoring AbortErrors could be useful independent of AbortSignals. So just from a technical architecture point of view putting it on DOMException made more sense to me. The OP's idea sounds good to me, and has precedent in .NET and other cancel-token using ecosystems. |
One option would be to add a global function AbortError(message="Aborted") {
throw new DOMException(message, "AbortError");
} In node it might vend something different (but still with While @jakearchibald's suggestion is great for checkpoints, it doesn't quite work for cases where you need to produce an function animationFrame(abortSignal) {
return new Promise((resolve, reject) => {
abortSignal?.assertNotAborted(); // Checkpoint use case as suggested in OP
const frameRequest = requestAnimationFrame(time => resolve(time));
abortSignal?.addEventListener("abort", () => {
cancelAnimationFrame(frameRequest);
reject(new AbortError()); // Case I'm suggesting, this isn't covered by OP
}, { once: true });
});
} |
Note that Node.js has |
Node.js doesn’t currently expose its DOMException and throws errors that look like the DOM AbortError but are not actually DOMExceptions (same name and same code but without some of the quirks - quite painful since Node.is codes have a different format) Of course in implemented DOM APIs Node will behave in a spec complaint way and throw a DOM AbortError. However since Node vendors certain bits of its core as user land modules (readable-stream) and exposing DOMException was a show stopper there we ended up with that compromise. I believe Jake Dor Robert Matteo and myself were on that call. We are open to changing this behavior. Note we currently do not expose our AbortError either. |
And I am +1 on adding A utility method like assertNotAborted I think that if that is done it should always throw the same DOMException AbortError regardless of environment. I am pretty content with Node.is absorbing the complexity of this and am happy to implement. |
If Node doesn't expose Just a thought I had, it could be possible to do it the other way around and have const controller = new AbortController();
controller.abort("user left the page");
const { signal } = controller;
signal.addEventListener("abort", ({ abortError }) => {
reject(abortError); // abortError has "user left the page" message
doCleanup();
});
signal.assertNotAborted(); // throws the Abort Error with message "user left the page" One bonus of this approach is the stack trace on the abort error would clearly show where the abort is triggered, which would massively help in tracing the origins of aborts. |
Basically it's up to userland to create a We can expose it (there has been talk of exposing the internal errors nodejs/node#34348 nodejs/node#14554 ) - honestly no one has asked for Node to expose AbortError yet. |
This is different to browsers, This is one reason I think it'd strongly be best if there was a global exposed in both Node and Browsers that could construct a "blessed" |
FYI, public Also, this just got a lot more complicated with node v17's native |
So the core reason for this issue has effectively been resolved by the addition of the new i.e. Instead of the original code in the OP we could now just have (roughly): AbortSignal.prototype.assertNotAborted = function() {
if (this.aborted) throw this.reason;
} |
Note that having |
Bit of a half baked idea, but should we make it easier to throw abort errors from signals? Something like:
I know it's a one-liner, but it might encourage using the right kind of error?
The text was updated successfully, but these errors were encountered: