-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
feat: add getAbortSignal()
#16266
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
feat: add getAbortSignal()
#16266
Conversation
🦋 Changeset detectedLatest commit: 1b5857f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
what if instead of aborting and passing a symbol, we passed an object with |
Ah so you'd do something like this? promise.catch((error) => {
if (error.stale) return;
throw error;
}); That could be nice and simple. Separately: not sure why the tests are failing in CI but not locally. Guess I'll try bumping the timeout |
@@ -27,6 +27,9 @@ export const LEGACY_PROPS = Symbol('legacy props'); | |||
export const LOADING_ATTR_SYMBOL = Symbol(''); | |||
export const PROXY_PATH_SYMBOL = Symbol('proxy path'); | |||
|
|||
// allow users to ignore aborted signal errors if `reason.stale` | |||
export const STALE_REACTION = { stale: true }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this but I think it needs some refinement... right now refined users of the best typed systems would have to do something like this:
promise.catch(e => {
if (typeof e === 'object' && Object.hasOwn(e, 'stale') && e.stale === true) {
// stuff
}
})
We either need to export an isStaleReactionAbortError
helper that does this and types it correctly or change tact. I would also think about making this a class extending Error
as right now it would fail an if (e instanceof Error)
check which is always a bad feeling when catching an error...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm. this is exactly the rabbit hole I wanted to avoid. my hunch/hope is that there will be vanishingly few situations where you actually need to do this check, and so my thinking was that we can punt on this for now (while adhering to reason.stale
being true
if we do make it an error in future)
just don't want #15844 to be held up by unnecessary bikeshedding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be fine punting on any type-related stuff but changing this to an error instance seems kinda essential, throwing non-Errors in any context where you expect users to catch them seems... bad
@@ -27,6 +27,12 @@ export const LEGACY_PROPS = Symbol('legacy props'); | |||
export const LOADING_ATTR_SYMBOL = Symbol(''); | |||
export const PROXY_PATH_SYMBOL = Symbol('proxy path'); | |||
|
|||
// allow users to ignore aborted signal errors if `reason.stale` | |||
export const STALE_REACTION = new (class StaleReactionError extends Error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nasty. effective. love it
if (reaction.ac !== null) { | ||
reaction.ac?.abort(STALE_REACTION); | ||
reaction.ac = null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (reaction.ac !== null) { | |
reaction.ac?.abort(STALE_REACTION); | |
reaction.ac = null; | |
} | |
reaction.ac?.abort(STALE_REACTION); | |
reaction.ac = null; |
I don't think the check is buying us anything here right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's saving us from writing reaction.ac
, which is more expensive than reading it. though it doesn't need to be optional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a couple of nits but lgtm now
Co-authored-by: Elliott Johnson <sejohnson@torchcloudconsulting.com>
Thats an amazing feature, great work! We will put it to a great use in our project. Another interesting possbile use is to pass a single AbortController to all the event subscriptions, to be able to cancel them all on component destraction. node.addEventListener('something', { signal: getAbortSignal() }) |
Can't find the docs of getAbortSignal @ https://svelte.dev, or at least the search doesn't pick up on it. |
Just merged a PR to update the docs, so it should be updated shortly. |
The getAbortSignal docs have code for async svelte |
This extracts
getAbortSignal()
from #15844, since it is (at least theoretically) independently useful and is easier to review in isolation.It may prove necessary to expose
STALE_REACTION
in some form, so that people can dosignal.reason === ???
inside a.catch
handler to determine whether or not to rethrow an error. But rather than get bogged down in design questions around what it should be called and where it should be exported from, I think we can safely cross that bridge later if we need to.Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.packages/svelte/src
, add a changeset (npx changeset
).Tests and linting
pnpm test
and lint the project withpnpm lint