improve(svm): add describeSolanaError helper#1446
Conversation
…xtraction
`SolanaError` carries the rich diagnostics (program logs, accounts touched,
underlying `TransactionError` / `InstructionError`) on its `context` and `cause`
fields. JSON loggers either replace an `Error` value with `.stack` or
`JSON.stringify` it; both routes silently drop those fields. Consumers end up
with `SolanaError: Transaction simulation failed at ...` and no way to tell a
benign race apart from a real program-error.
Add `describeSolanaError(err)` next to `isSolanaError` in `arch/svm/provider`.
Returns `{ solanaError: { name, message?, code, context, cause? } }` for
SolanaErrors (recursing on SolanaError causes; falling back to `{ message }` for
non-Solana Error causes) and `{}` otherwise so callers can spread the result
unconditionally:
catch (err) {
logger.error({ ..., error: err, ...describeSolanaError(err) });
}
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
| } | ||
|
|
||
| /** | ||
| * Structured description of a SolanaError suitable for logging. |
There was a problem hiding this comment.
Comments in this file are too verbose - make them concise.
There was a problem hiding this comment.
Trimmed the JSDoc/block comments in src/arch/svm/provider.ts in 14f034f — kept terse one-liners over isSolanaError, SolanaErrorStruct, and SolanaErrorDescription, and condensed the describeSolanaError JSDoc to motivation + usage.
There was a problem hiding this comment.
Does this file belong under test/provider/svm ? Colocated with other SVM provider tests?
There was a problem hiding this comment.
Good catch — moved to test/providers/solana/describeSolanaError.test.ts alongside quorumFallbackRpcFactory.test.ts and utils.test.ts in 14f034f.
- Trim verbose JSDoc/block comments in src/arch/svm/provider.ts. - Move describeSolanaError.test.ts under test/providers/solana/ alongside the other SVM provider tests. Addresses pxrl review feedback on #1446. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Addressed pxrl's review on #1446 in commit
Verified: |
| /** | ||
| * SVM RPC provider error codes | ||
| * See https://www.quicknode.com/docs/solana/error-references | ||
| */ |
There was a problem hiding this comment.
@droplet-rl Don't re-word existing comments unless their content is being changed.
There was a problem hiding this comment.
Apologies — I misread the earlier review as flagging the whole file. Reverted the pre-existing JSDoc blocks (SVM error-code exports, SolanaErrorStruct, SolanaErrorLike, isSolanaError) to their original wording in 149ed9c. Only the new describeSolanaError JSDoc remains trimmed.
Revert the changes to JSDoc blocks for SVM error-code exports, SolanaErrorStruct, SolanaErrorLike, and isSolanaError back to their original wording; their content was not being changed by this PR. The new describeSolanaError JSDoc remains as-is (terse, motivation + usage). Addresses pxrl review feedback on #1446. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Addressed pxrl's follow-up review on #1446 in commit The feedback: I'd overreached on the first round — pxrl meant don't re-word existing comments in Net diff vs. the PR base is now strictly additive: the new Verified: |
Summary
Add
describeSolanaError(err)next toisSolanaErrorinsrc/arch/svm/provider.ts. Pure transform; returns a plain object holding the SolanaError diagnostic fields (name, optionalmessage,code,context, recursively-describedcause) that JSON loggers would otherwise drop, and{}for anything that isn't a SolanaError so callers can spread it unconditionally:Why
A
SolanaErrorkeeps the rich diagnostics (programlogs[],accounts,unitsConsumed, plus the wrappedTransactionError/InstructionError) on itscontextandcausefields. Most JSON loggers either replace anErrorvalue with.stack(e.g.@risk-labs/logger'serrorStackTracerFormatter) orJSON.stringifyit — andError.stack/Error.message/Error.nameare non-enumerable on the prototype, so the structured payload that SolanaError adds gets silently dropped. The relayer dataworker is hitting this today on SVM refund-leaf execution failures: prod logs read onlySolanaError: Transaction simulation failed at /across-relayer/node_modules/@solana/rpc-transformers/dist/index.node.cjs:332:22 …, with no way to tell whether it was a benign already-executed race, a stale blockhash, a custom program error, or RPC flake.A private copy of this helper landed in
across-protocol/relayer#3422to unblock prod visibility. Moving it down to the SDK so the other consumers (indexer,relayer-madrid,quote-api, anything callingarch.svm.*) can share it. The relayer-side follow-up will swap its local copy for this SDK export.Shape
For a preflight-failure SolanaError,
describeSolanaError(err)now returns (in addition to whatever the logger does witherror: err):{ "solanaError": { "name": "SolanaError", "message": "Transaction simulation failed", "code": -32002, "context": { "__code": -32002, "logs": ["Program log: refund leaf already executed"], "accounts": null, "unitsConsumed": 4321 }, "cause": { "name": "SolanaError", "code": 4615001, "context": { "__code": 4615001, "index": 3 } } } }Mirrors the structural-clone resilience that
isSolanaErroralready has: the helper works whether the input is a liveSolanaErrorinstance or a JSON round-tripped object that lost its prototype chain.Test plan
yarn lint-check(clean)npx hardhat test test/describeSolanaError.test.ts(7 new unit tests pass — covers non-Solana inputs, plain SolanaError-like objects, Error subclasses, nested SolanaError causes, non-Solana Error causes, no-cause case, JSON serialization round-trips)bots-across-3839Cloud Run logs after deployThread: #bot-monitoring 1779869895.829509
🤖 Generated with Claude Code