fix(wallets): surface transactionId and status on 5xx transaction API failures#1977
fix(wallets): surface transactionId and status on 5xx transaction API failures#1977alfonso-paella wants to merge 1 commit into
Conversation
Co-Authored-By: Alfonso <alfonso@paella.dev>
Original prompt from Alfonso
|
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
🦋 Changeset detectedLatest commit: fb02f0f The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
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 |
Description
A customer reported that their first
sendTransactionon a Solana smart wallet (which triggers the on-chainAddSignerbootstrap) landed successfully on-chain, but the SDK raised a bare"API request failed: 500"to the client. An unrecoverable-looking error on an operation that actually succeeded invites a naive retry — in a trading context that means double-buy risk.Root cause:
ApiClient.makeRequest(common base) throwsApiClientErroron any 5xx regardless of the operation's actual outcome, and no layer of the create/approve/poll pipeline attaches thetransactionIdbefore the error reaches the caller — even at approve/poll sites where the ID is already known locally. (PR #1966's polling rework did not change error propagation.)This PR keeps the pipeline unchanged and adds the smallest reconciliation path: a new exported
TransactionApiError extends CrossmintSDKErrorcarryingtransactionId?andstatus?, plus awrapTransactionApiError(error, transactionId?)helper applied at each throw site:Behavioral change: a 5xx during create/approve/poll now throws
TransactionApiErrorinstead of a rawApiClientError. When the transaction ID is known, the message includes(transactionId: ...)and guidance to check status before retrying; when unknown (opaque create 5xx), the message states the outcome is indeterminate. Clients can catchTransactionApiError, readerror.transactionId, and reconcile (e.g. fetch transaction status) instead of blindly retryingsendTransaction.Open product question: this PR deliberately re-throws (does not swallow) 5xx even when the transaction may have succeeded — swallowing vs. polling-through on create-5xx is a product decision. The safe minimal change here only makes the error reconcilable.
Test plan
@crossmint/wallets-sdk:{"id": ...}body →TransactionApiErrorwithtransactionIdsetTransactionApiErrorwithstatusset,transactionIdundefined, "indeterminate" messagetransactionIdattachedtransactionIdattachedpnpm lint,pnpm --filter @crossmint/wallets-sdk... build && pnpm --filter @crossmint/wallets-sdk test:vitest(653 passed, 68 skipped integration)Package updates
@crossmint/wallets-sdk— patch changeset added (.changeset/quiet-wombats-reconcile-transaction-5xx.md)Link to Devin session: https://crossmint.devinenterprise.com/sessions/57c0d09399aa4688aaef9347747ff79d
Requested by: @alfonso-paella