feat: normalize contract errors into actionable messages - #930
Merged
greatest0fallt1me merged 1 commit intoAug 29, 2026
Merged
Conversation
Map raw Soroban/Stellar/wallet errors to structured NormalizedError objects with user-safe title, description, actionHint, isRetryable, and isSensitive fields. - Add lib/stellar/contract-error-normalizer.ts - ContractErrorCode enum (24 codes: contract indices #1-Predictify-org#5, Horizon tx_*/op_* codes, wallet states, network errors) - normalizeContractError(rawError?, resultCodes?) — pure, stateless, 8-step classification precedence - normalizeFromFailureType() — maps TransactionFailureType to NormalizedError for use in useTransaction hook - Invariant: title/description/actionHint never expose addresses, hashes, or raw Soroban error internals - Update lib/stellar/transaction.ts - normalizeErrorMessage() routes Horizon payloads through normalizer - Add normalizeTransactionError() export for structured output - Catch blocks use normalizeContractError().description - Update hooks/useTransaction.hook.ts - Toast title/description use normalizeFromFailureType() - Raw error preserved in transactionError state for compatibility - Add missing useRef import - Update hooks/useWallet.hook.ts - error state holds normalized description; raw to console.error only - Add lib/stellar/__tests__/contract-error-normalizer.test.ts (132 tests) - All 24 error codes, Soroban indices, WASM trap, Horizon codes, wallet patterns, priority ordering, boundary cases, sensitive data invariants, isRetryable semantics, concurrency/statelessness - Update lib/stellar/__tests__/transaction.test.ts - Assert normalized description instead of raw tx_bad_auth code Tests: 139 passed, 0 failed
|
@Bobai100 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
@Bobai100 is attempting to deploy a commit to the Jagadeesh B's projects Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces raw Soroban/Stellar/wallet error strings surfaced to users with structured, human-readable
messages that include a title, explanation, and concrete next step. Previously, errors like tx_bad_auth
or Error(Contract, #4) were shown directly to users or silently swallowed. Now every error path produces
consistent, actionable copy.
Changes
New: lib/stellar/contract-error-normalizer.ts
TooManyMarkets, PlanTooLarge, Overflow, MarketNotFound, NotInitialized), Horizon tx_/op_ result codes,
wallet states, and network errors
and raw fields
precedence (Soroban index → WASM trap → Horizon op codes → Horizon tx codes → confirmation timeout →
wallet errors → network errors → unknown)
NormalizedError
internal error representations
Updated: lib/stellar/transaction.ts
"The transaction signature was rejected by the network."
Updated: hooks/useTransaction.hook.ts
your wallet is unlocked and try signing again." instead of a raw code
callers
Updated: hooks/useWallet.hook.ts
Security & observability
the raw field in UI
Tests
Soroban contract indices, WASM trap/panic patterns, Horizon tx_/op_ codes via both resultCodes and raw
strings, all wallet error patterns, 8-step priority ordering, boundary cases
(undefined/empty/whitespace/null), sensitive data invariants, isRetryable semantics,
normalizeFromFailureType mapping, and concurrency/statelessness
result codes (the old assertion was the bug being fixed)
Compatibility
Existing callers of useTransaction are unaffected — transactionError state still holds the raw error
string. Only the toast display layer uses normalized copy. The submitTransaction / pollForConfirmation
return shape is unchanged (error field now holds a user-safe string rather than a raw code, which is
strictly an improvement).
closes #900