Skip to content

Add isAbortError to @solana/promises#1549

Merged
mcintyre94 merged 1 commit into
mainfrom
is-abort-error
Apr 21, 2026
Merged

Add isAbortError to @solana/promises#1549
mcintyre94 merged 1 commit into
mainfrom
is-abort-error

Conversation

@mcintyre94
Copy link
Copy Markdown
Member

@mcintyre94 mcintyre94 commented Apr 21, 2026

Summary of Changes

This PR adds a new function isAbortError to @solana/promises

It provides an easy way to filter for an abort error, in the same way we do with isSolanaError. Pairs with getAbortablePromise, but useful for anything throwing abort errors (like fetch) too.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 21, 2026

🦋 Changeset detected

Latest commit: 6e1e66f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 46 packages
Name Type
@solana/promises Minor
@solana/instruction-plans Minor
@solana/keys Minor
@solana/react Minor
@solana/rpc-subscriptions-spec Minor
@solana/rpc-subscriptions Minor
@solana/transaction-confirmation Minor
@solana/wallet-account-signer Minor
@solana/kit Minor
@solana/plugin-interfaces Minor
@solana/program-client-core Minor
@solana/compat Minor
@solana/offchain-messages Minor
@solana/rpc-api Minor
@solana/rpc-graphql Minor
@solana/rpc-subscriptions-api Minor
@solana/signers Minor
@solana/transactions Minor
@solana/rpc-subscriptions-channel-websocket Minor
@solana/rpc Minor
@solana/sysvars Minor
@solana/accounts Minor
@solana/addresses Minor
@solana/assertions Minor
@solana/codecs-core Minor
@solana/codecs-data-structures Minor
@solana/codecs-numbers Minor
@solana/codecs-strings Minor
@solana/codecs Minor
@solana/errors Minor
@solana/fast-stable-stringify Minor
@solana/functional Minor
@solana/instructions Minor
@solana/nominal-types Minor
@solana/options Minor
@solana/plugin-core Minor
@solana/programs Minor
@solana/rpc-parsed-types Minor
@solana/rpc-spec-types Minor
@solana/rpc-spec Minor
@solana/rpc-transformers Minor
@solana/rpc-transport-http Minor
@solana/rpc-types Minor
@solana/subscribable Minor
@solana/transaction-messages Minor
@solana/webcrypto-ed25519-polyfill Minor

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

Copy link
Copy Markdown
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@bundlemon
Copy link
Copy Markdown

bundlemon Bot commented Apr 21, 2026

BundleMon

Files updated (3)
Status Path Size Limits
promises/dist/index.native.mjs
841B (+43B +5.39%) -
promises/dist/index.node.mjs
840B (+43B +5.4%) -
promises/dist/index.browser.mjs
839B (+40B +5.01%) -
Unchanged files (141)
Status Path Size Limits
@solana/kit production bundle
kit/dist/index.production.min.js
47.45KB -
errors/dist/index.node.mjs
19.66KB -
errors/dist/index.browser.mjs
19.64KB -
errors/dist/index.native.mjs
19.64KB -
rpc-graphql/dist/index.browser.mjs
18.82KB -
rpc-graphql/dist/index.native.mjs
18.81KB -
rpc-graphql/dist/index.node.mjs
18.81KB -
wallet-account-signer/dist/index.node.mjs
16.67KB -
wallet-account-signer/dist/index.native.mjs
16.65KB -
wallet-account-signer/dist/index.browser.mjs
16.65KB -
transaction-messages/dist/index.browser.mjs
11.32KB -
transaction-messages/dist/index.native.mjs
11.32KB -
transaction-messages/dist/index.node.mjs
11.32KB -
instruction-plans/dist/index.browser.mjs
6.58KB -
instruction-plans/dist/index.native.mjs
6.58KB -
instruction-plans/dist/index.node.mjs
6.58KB -
codecs-data-structures/dist/index.browser.mjs
5.04KB -
codecs-data-structures/dist/index.native.mjs
5.03KB -
codecs-data-structures/dist/index.node.mjs
5.03KB -
offchain-messages/dist/index.browser.mjs
4.89KB -
offchain-messages/dist/index.native.mjs
4.89KB -
offchain-messages/dist/index.node.mjs
4.89KB -
transactions/dist/index.browser.mjs
4.07KB -
transactions/dist/index.native.mjs
4.07KB -
transactions/dist/index.node.mjs
4.07KB -
kit/dist/index.browser.mjs
3.72KB -
kit/dist/index.native.mjs
3.72KB -
kit/dist/index.node.mjs
3.72KB -
codecs-core/dist/index.browser.mjs
3.62KB -
codecs-core/dist/index.native.mjs
3.62KB -
codecs-core/dist/index.node.mjs
3.62KB -
webcrypto-ed25519-polyfill/dist/index.node.mj
s
3.61KB -
webcrypto-ed25519-polyfill/dist/index.browser
.mjs
3.59KB -
webcrypto-ed25519-polyfill/dist/index.native.
mjs
3.57KB -
rpc-subscriptions/dist/index.browser.mjs
3.37KB -
rpc-subscriptions/dist/index.node.mjs
3.34KB -
rpc-subscriptions/dist/index.native.mjs
3.31KB -
signers/dist/index.browser.mjs
3.26KB -
signers/dist/index.native.mjs
3.26KB -
signers/dist/index.node.mjs
3.26KB -
rpc-transformers/dist/index.browser.mjs
3.16KB -
rpc-transformers/dist/index.native.mjs
3.16KB -
rpc-transformers/dist/index.node.mjs
3.16KB -
react/dist/index.browser.mjs
3.09KB -
react/dist/index.native.mjs
3.09KB -
react/dist/index.node.mjs
3.09KB -
keys/dist/index.node.mjs
3.06KB -
addresses/dist/index.browser.mjs
2.93KB -
addresses/dist/index.native.mjs
2.92KB -
addresses/dist/index.node.mjs
2.92KB -
keys/dist/index.browser.mjs
2.85KB -
keys/dist/index.native.mjs
2.85KB -
codecs-strings/dist/index.browser.mjs
2.55KB -
codecs-strings/dist/index.node.mjs
2.51KB -
codecs-strings/dist/index.native.mjs
2.47KB -
transaction-confirmation/dist/index.node.mjs
2.41KB -
sysvars/dist/index.browser.mjs
2.37KB -
sysvars/dist/index.native.mjs
2.37KB -
sysvars/dist/index.node.mjs
2.37KB -
transaction-confirmation/dist/index.native.mj
s
2.36KB -
transaction-confirmation/dist/index.browser.m
js
2.35KB -
rpc-subscriptions-spec/dist/index.node.mjs
2.21KB -
rpc-subscriptions-spec/dist/index.native.mjs
2.17KB -
rpc-subscriptions-spec/dist/index.browser.mjs
2.16KB -
subscribable/dist/index.node.mjs
1.97KB -
rpc/dist/index.node.mjs
1.95KB -
codecs-numbers/dist/index.browser.mjs
1.95KB -
codecs-numbers/dist/index.native.mjs
1.95KB -
codecs-numbers/dist/index.node.mjs
1.94KB -
subscribable/dist/index.native.mjs
1.92KB -
subscribable/dist/index.browser.mjs
1.91KB -
rpc-transport-http/dist/index.browser.mjs
1.91KB -
rpc-transport-http/dist/index.native.mjs
1.9KB -
rpc/dist/index.native.mjs
1.81KB -
rpc/dist/index.browser.mjs
1.8KB -
rpc-transport-http/dist/index.node.mjs
1.72KB -
rpc-types/dist/index.browser.mjs
1.53KB -
rpc-types/dist/index.native.mjs
1.53KB -
rpc-types/dist/index.node.mjs
1.53KB -
rpc-subscriptions-channel-websocket/dist/inde
x.node.mjs
1.33KB -
rpc-subscriptions-channel-websocket/dist/inde
x.native.mjs
1.27KB -
rpc-subscriptions-channel-websocket/dist/inde
x.browser.mjs
1.26KB -
program-client-core/dist/index.browser.mjs
1.21KB -
program-client-core/dist/index.native.mjs
1.21KB -
program-client-core/dist/index.node.mjs
1.21KB -
options/dist/index.browser.mjs
1.18KB -
options/dist/index.native.mjs
1.18KB -
options/dist/index.node.mjs
1.17KB -
accounts/dist/index.browser.mjs
1.17KB -
accounts/dist/index.native.mjs
1.17KB -
accounts/dist/index.node.mjs
1.16KB -
rpc-api/dist/index.browser.mjs
976B -
rpc-api/dist/index.native.mjs
975B -
rpc-api/dist/index.node.mjs
973B -
compat/dist/index.browser.mjs
969B -
compat/dist/index.native.mjs
968B -
compat/dist/index.node.mjs
966B -
rpc-spec-types/dist/index.browser.mjs
962B -
rpc-spec-types/dist/index.native.mjs
961B -
rpc-spec-types/dist/index.node.mjs
959B -
rpc-subscriptions-api/dist/index.native.mjs
870B -
rpc-subscriptions-api/dist/index.node.mjs
869B -
rpc-subscriptions-api/dist/index.browser.mjs
868B -
rpc-spec/dist/index.browser.mjs
852B -
rpc-spec/dist/index.native.mjs
851B -
rpc-spec/dist/index.node.mjs
850B -
assertions/dist/index.browser.mjs
783B -
instructions/dist/index.browser.mjs
771B -
instructions/dist/index.native.mjs
770B -
instructions/dist/index.node.mjs
768B -
plugin-core/dist/index.browser.mjs
749B -
plugin-core/dist/index.native.mjs
749B -
plugin-core/dist/index.node.mjs
747B -
fast-stable-stringify/dist/index.browser.mjs
726B -
fast-stable-stringify/dist/index.native.mjs
725B -
assertions/dist/index.native.mjs
724B -
fast-stable-stringify/dist/index.node.mjs
724B -
assertions/dist/index.node.mjs
723B -
programs/dist/index.browser.mjs
329B -
programs/dist/index.native.mjs
327B -
programs/dist/index.node.mjs
325B -
fs-impl/dist/index.browser.mjs
245B -
event-target-impl/dist/index.node.mjs
230B -
functional/dist/index.browser.mjs
154B -
functional/dist/index.native.mjs
152B -
text-encoding-impl/dist/index.native.mjs
152B -
functional/dist/index.node.mjs
151B -
codecs/dist/index.browser.mjs
137B -
codecs/dist/index.native.mjs
136B -
codecs/dist/index.node.mjs
134B -
event-target-impl/dist/index.browser.mjs
133B -
ws-impl/dist/index.node.mjs
131B -
text-encoding-impl/dist/index.browser.mjs
122B -
fs-impl/dist/index.node.mjs
120B -
text-encoding-impl/dist/index.node.mjs
119B -
ws-impl/dist/index.browser.mjs
113B -
crypto-impl/dist/index.node.mjs
111B -
crypto-impl/dist/index.browser.mjs
109B -
rpc-parsed-types/dist/index.browser.mjs
66B -
rpc-parsed-types/dist/index.native.mjs
65B -
rpc-parsed-types/dist/index.node.mjs
63B -

Total files change +126B +0.02%

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Documentation Preview: https://kit-docs-e7syjl5cf-anza-tech.vercel.app

@mcintyre94
Copy link
Copy Markdown
Member Author

@trevor-cortex

Copy link
Copy Markdown

@trevor-cortex trevor-cortex left a comment

Choose a reason for hiding this comment

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

Nice, tidy addition. Adds isAbortError(err) to @solana/promises as a narrow predicate — err instanceof Error && err.name === 'AbortError' — so callers don't have to instanceof-check each platform's error class. Pairs well with getAbortablePromise and standard fetch abort behavior.

What looks good

  • Export is automatic via the existing export * from './abortable' in src/index.ts, no index change needed.
  • minor changeset is correct for a new public API.
  • JSDoc follows the repo's docblock skill (summary, @example, @see {@link getAbortablePromise}).
  • README section mirrors the style of the adjacent getAbortablePromise entry.
  • Tests cover the happy path, a subclass, the real abort flow through getAbortablePromise, and the main negative cases (regular Error, TypeError, duck-typed object, undefined, null). expect.assertions(1) is correctly used only in the async test, per CLAUDE.md.

For subsequent reviewers

  • The docblock specifically mentions DOMException as the real-world aborted-fetch rejection, but the tests simulate it with Object.assign(new Error(), { name: 'AbortError' }) rather than a real new DOMException('...', 'AbortError'). DOMException extends Error in all environments Kit targets (Node ≥17 current/lts, browsers, RN) so the predicate works, but a direct DOMException test would tie the behavior more tightly to the documented use case. Non-blocking.
  • Worth sanity-checking that @solana/promises genuinely isn't intended to be re-exported from the @solana/kit facade — it currently isn't (neither getAbortablePromise nor the new isAbortError will be reachable from @solana/kit). That's pre-existing and out of scope for this PR, just flagging.

it('returns `false` for a non-`Error` object whose `name` is `AbortError`', () => {
expect(isAbortError({ name: 'AbortError' })).toBe(false);
});
it('returns `false` for `undefined`', () => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Optional: since the docblock specifically calls out DOMException as the real-world aborted-fetch rejection shape, consider adding a case that uses the real thing:

it('returns `true` for a `DOMException` whose `name` is `AbortError`', () => {
    expect(isAbortError(new DOMException('The operation was aborted.', 'AbortError'))).toBe(true);
});

This exercises the instanceof Error branch against the actual platform class rather than a synthesized Error with a patched name, and guards against any future environment where DOMException stops extending Error. Non-blocking.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good idea - had to add this as a browser only test because of a limitation of Jest's node env.

@mcintyre94 mcintyre94 marked this pull request as ready for review April 21, 2026 10:31
Copy link
Copy Markdown
Member

@lorisleiva lorisleiva left a comment

Choose a reason for hiding this comment

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

Thanks! I double-checked and it also works when passing nothing to AbortController.abort (See playground). nit: Maybe we could add a test case like this.

Adds `isAbortError(err)` to `@solana/promises`. The helper narrows `unknown` to `Error` and returns `true` when the error's `name` is `'AbortError'` — the convention used by `DOMException` and by `AbortController`-aware APIs like `fetch`. Callers catching rejections from `getAbortablePromise`, superseded operations, or other abort-aware flows can use this to distinguish intentional cancellation from real failures without having to `instanceof`-check every platform-specific error class.

Ships with test coverage across Node and browser environments and a README entry demonstrating the try/catch pattern alongside `getAbortablePromise`.
@mcintyre94
Copy link
Copy Markdown
Member Author

Nice, thanks! Added to the browser tests because it has the same quirk in Jest's Node environment.

@mcintyre94 mcintyre94 enabled auto-merge April 21, 2026 12:29
@mcintyre94 mcintyre94 added this pull request to the merge queue Apr 21, 2026
Merged via the queue into main with commit 8d73de5 Apr 21, 2026
14 checks passed
@mcintyre94 mcintyre94 deleted the is-abort-error branch April 21, 2026 12:41
@github-actions
Copy link
Copy Markdown
Contributor

🔎💬 Inkeep AI search and chat service is syncing content for source 'Solana Kit Docs'

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Because there has been no activity on this PR for 14 days since it was merged, it has been automatically locked. Please open a new issue if it requires a follow up.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators May 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants