Skip to content

Handle code-less JSON RPC errors #130

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

Merged
merged 1 commit into from
Feb 27, 2025

Conversation

lorisleiva
Copy link
Member

@lorisleiva lorisleiva commented Feb 21, 2025

Problem

I've had reports that some RPC errors do not include a code attribute in their response. For instance:

{
    "id": "25",
    "jsonrpc": "2.0",
    "error": {
        "message": "No RPC endpoints available"
    }
}

Because our types strongly expect a bigint | number code to be provided in the response, the getSolanaErrorFromJsonRpcError function of the @solana/errors package doesn't gracefully handle this use-case and throws the following unhelpful error stack.

error: TypeError: Cannot read properties of undefined (reading 'length')
        at getHumanReadableErrorMessage (webpack-internal:///../../../node_modules/.pnpm/@solana+errors@2.0.0_typescript@5.7.2/node_modules/@solana/errors/dist/index.node.cjs:493:27)
        at getErrorMessage (webpack-internal:///../../../node_modules/.pnpm/@solana+errors@2.0.0_typescript@5.7.2/node_modules/@solana/errors/dist/index.node.cjs:550:12)
        at new SolanaError (webpack-internal:///../../../node_modules/.pnpm/@solana+errors@2.0.0_typescript@5.7.2/node_modules/@solana/errors/dist/index.node.cjs:580:21)
        at Object.getSolanaErrorFromJsonRpcError (webpack-internal:///../../../node_modules/.pnpm/@solana+errors@2.0.0_typescript@5.7.2/node_modules/@solana/errors/dist/index.node.cjs:817:11)
        at eval (webpack-internal:///../../../node_modules/.pnpm/@solana+rpc-transformers@2.0.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.7.2/node_modules/@solana/rpc-transformers/dist/index.node.cjs:254:20)
        at eval (webpack-internal:///../../../node_modules/.pnpm/@solana+rpc-transformers@2.0.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.7.2/node_modules/@solana/rpc-transformers/dist/index.node.cjs:267:54)
        at eval (webpack-internal:///../../../node_modules/.pnpm/@solana+functional@2.0.0_typescript@5.7.2/node_modules/@solana/functional/dist/index.node.cjs:5:34)
        at Array.reduce (<anonymous>)
        at Object.pipe (webpack-internal:///../../../node_modules/.pnpm/@solana+functional@2.0.0_typescript@5.7.2/node_modules/@solana/functional/dist/index.node.cjs:5:14)
        at Object.eval [as responseTransformer] (webpack-internal:///../../../node_modules/.pnpm/@solana+rpc-transformers@2.0.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.7.2/node_modules/@solana/rpc-transformers/dist/index.node.cjs:265:23)

Summary of Changes

This PR fixes this by introducing a new SOLANA_ERROR__UNRECOGNIZED_JSON_RPC_ERROR error which gracefully tackles the case where a code isn't part of the RPC response.

Copy link

changeset-bot bot commented Feb 21, 2025

🦋 Changeset detected

Latest commit: 6ee04a2

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

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
Member Author

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

Copy link

bundlemon bot commented Feb 21, 2025

BundleMon

Files updated (4)
Status Path Size Limits
errors/dist/index.browser.mjs
14.47KB (+271B +1.86%) -
errors/dist/index.native.mjs
14.46KB (+271B +1.86%) -
errors/dist/index.node.mjs
14.49KB (+271B +1.86%) -
@solana/web3.js production bundle
library/dist/index.production.min.js
34.03KB (+131B +0.38%) -
Unchanged files (123)
Status Path Size Limits
rpc-graphql/dist/index.browser.mjs
18.77KB -
rpc-graphql/dist/index.native.mjs
18.77KB -
rpc-graphql/dist/index.node.mjs
18.76KB -
transaction-messages/dist/index.browser.mjs
7.06KB -
transaction-messages/dist/index.native.mjs
7.06KB -
transaction-messages/dist/index.node.mjs
7.05KB -
codecs-data-structures/dist/index.browser.mjs
4.77KB -
codecs-data-structures/dist/index.native.mjs
4.77KB -
codecs-data-structures/dist/index.node.mjs
4.76KB -
webcrypto-ed25519-polyfill/dist/index.node.mj
s
3.58KB -
webcrypto-ed25519-polyfill/dist/index.browser
.mjs
3.56KB -
webcrypto-ed25519-polyfill/dist/index.native.
mjs
3.54KB -
rpc-subscriptions/dist/index.browser.mjs
3.38KB -
rpc-subscriptions/dist/index.node.mjs
3.34KB -
rpc-subscriptions/dist/index.native.mjs
3.31KB -
codecs-core/dist/index.browser.mjs
3.3KB -
codecs-core/dist/index.native.mjs
3.3KB -
codecs-core/dist/index.node.mjs
3.3KB -
rpc-transformers/dist/index.browser.mjs
2.92KB -
rpc-transformers/dist/index.native.mjs
2.92KB -
rpc-transformers/dist/index.node.mjs
2.92KB -
addresses/dist/index.browser.mjs
2.86KB -
addresses/dist/index.native.mjs
2.86KB -
addresses/dist/index.node.mjs
2.86KB -
library/dist/index.browser.mjs
2.71KB -
library/dist/index.native.mjs
2.71KB -
library/dist/index.node.mjs
2.71KB -
codecs-strings/dist/index.browser.mjs
2.53KB -
signers/dist/index.browser.mjs
2.53KB -
signers/dist/index.native.mjs
2.53KB -
signers/dist/index.node.mjs
2.53KB -
codecs-strings/dist/index.node.mjs
2.49KB -
codecs-strings/dist/index.native.mjs
2.46KB -
transaction-confirmation/dist/index.node.mjs
2.4KB -
transaction-confirmation/dist/index.native.mj
s
2.34KB -
transaction-confirmation/dist/index.browser.m
js
2.34KB -
sysvars/dist/index.browser.mjs
2.25KB -
sysvars/dist/index.native.mjs
2.25KB -
sysvars/dist/index.node.mjs
2.24KB -
rpc-subscriptions-spec/dist/index.node.mjs
2.13KB -
rpc-subscriptions-spec/dist/index.native.mjs
2.08KB -
rpc-subscriptions-spec/dist/index.browser.mjs
2.08KB -
keys/dist/index.browser.mjs
2.04KB -
keys/dist/index.native.mjs
2.03KB -
keys/dist/index.node.mjs
2.03KB -
codecs-numbers/dist/index.native.mjs
2.01KB -
codecs-numbers/dist/index.browser.mjs
2.01KB -
codecs-numbers/dist/index.node.mjs
2.01KB -
transactions/dist/index.browser.mjs
1.99KB -
transactions/dist/index.native.mjs
1.99KB -
react/dist/index.native.mjs
1.99KB -
transactions/dist/index.node.mjs
1.99KB -
react/dist/index.browser.mjs
1.99KB -
react/dist/index.node.mjs
1.99KB -
rpc/dist/index.node.mjs
1.96KB -
rpc-transport-http/dist/index.browser.mjs
1.91KB -
rpc-transport-http/dist/index.native.mjs
1.91KB -
rpc/dist/index.native.mjs
1.81KB -
subscribable/dist/index.node.mjs
1.8KB -
rpc/dist/index.browser.mjs
1.8KB -
subscribable/dist/index.native.mjs
1.75KB -
subscribable/dist/index.browser.mjs
1.74KB -
rpc-transport-http/dist/index.node.mjs
1.73KB -
rpc-types/dist/index.browser.mjs
1.6KB -
rpc-types/dist/index.native.mjs
1.6KB -
rpc-types/dist/index.node.mjs
1.6KB -
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 -
options/dist/index.browser.mjs
1.18KB -
options/dist/index.native.mjs
1.18KB -
options/dist/index.node.mjs
1.18KB -
accounts/dist/index.browser.mjs
1.13KB -
accounts/dist/index.native.mjs
1.12KB -
accounts/dist/index.node.mjs
1.12KB -
compat/dist/index.browser.mjs
972B -
compat/dist/index.native.mjs
971B -
compat/dist/index.node.mjs
970B -
rpc-spec-types/dist/index.browser.mjs
964B -
rpc-api/dist/index.browser.mjs
963B -
rpc-api/dist/index.native.mjs
962B -
rpc-spec-types/dist/index.native.mjs
962B -
rpc-api/dist/index.node.mjs
961B -
rpc-spec-types/dist/index.node.mjs
961B -
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
829B -
rpc-spec/dist/index.native.mjs
829B -
rpc-spec/dist/index.node.mjs
828B -
promises/dist/index.browser.mjs
799B -
promises/dist/index.native.mjs
798B -
promises/dist/index.node.mjs
797B -
assertions/dist/index.browser.mjs
780B -
instructions/dist/index.browser.mjs
772B -
instructions/dist/index.native.mjs
771B -
instructions/dist/index.node.mjs
769B -
fast-stable-stringify/dist/index.browser.mjs
723B -
assertions/dist/index.native.mjs
722B -
fast-stable-stringify/dist/index.native.mjs
722B -
fast-stable-stringify/dist/index.node.mjs
721B -
assertions/dist/index.node.mjs
720B -
programs/dist/index.browser.mjs
329B -
programs/dist/index.native.mjs
327B -
programs/dist/index.node.mjs
325B -
event-target-impl/dist/index.node.mjs
233B -
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 -
text-encoding-impl/dist/index.node.mjs
119B -
crypto-impl/dist/index.node.mjs
114B -
ws-impl/dist/index.browser.mjs
113B -
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 +944B +0.27%

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

@lorisleiva lorisleiva force-pushed the 02-21-handle_code-less_json_rpc_errors branch from 271c7a7 to eba7948 Compare February 21, 2025 17:58
@lorisleiva lorisleiva marked this pull request as ready for review February 21, 2025 22:22
@Jac0xb
Copy link

Jac0xb commented Feb 23, 2025

appreciate u!

@@ -40,6 +41,13 @@ describe('getSolanaErrorFromJsonRpcError', () => {
const error = getSolanaErrorFromJsonRpcError({ code, message: 'o no' });
expect(error).toHaveProperty('context.__code', 123);
});
it('produces a `SOLANA_ERROR__UNRECOGNIZED_JSON_RPC_ERROR` when no code is given', () => {
Copy link

Choose a reason for hiding this comment

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

I think the actual conditional that invokes getSolanaErrorFromJsonRpcError looks like "error" in data and if it is it calls this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm I think that according to the specs if the JSON RPC returns a response whose payload does not include an "error" attribute, it should not be treated as an error.

Therefore, the only thing we need to handle is a fallback for an "error" object we do not recognise — i.e. no error code provided.

mcintyre94
mcintyre94 previously approved these changes Feb 24, 2025
steveluscher
steveluscher previously approved these changes Feb 24, 2025
Copy link
Collaborator

@steveluscher steveluscher left a comment

Choose a reason for hiding this comment

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

Just to be completely clear for future readers, this is a patch to gracefully handle JSON-RPC that do not comply with the spec. https://www.jsonrpc.org/specification#error_object

@lorisleiva lorisleiva force-pushed the 02-21-handle_code-less_json_rpc_errors branch from eba7948 to 6ee04a2 Compare February 26, 2025 13:19
@github-actions github-actions bot dismissed stale reviews from mcintyre94 and steveluscher February 26, 2025 13:20

Your organization requires reapproval when changes are made, so Graphite has dismissed approvals. See the output of git range-diff at https://github.com/anza-xyz/solana-web3.js/actions/runs/13544848140

@lorisleiva lorisleiva merged commit c7b7dd9 into main Feb 27, 2025
12 checks passed
@lorisleiva lorisleiva deleted the 02-21-handle_code-less_json_rpc_errors branch February 27, 2025 15:32
@github-actions github-actions bot mentioned this pull request Feb 4, 2025
Copy link
Contributor

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 Mar 14, 2025
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.

4 participants