Skip to content

docs(errors): add client-side error handling guide #43

Description

@Demilade10

Description

This documentation-only issue adds a practical guide for wallet, dashboard, and subscription-management developers handling PayStream failures through the Stellar JavaScript SDK.

The guide complements the catalog in #41: the catalog defines errors, while this guide explains detection, provenance, retry safety, and user-facing responses.

Blocked by #41. If #42 is merged before this work begins, reuse or reference its proven parsing/provenance approach rather than publishing conflicting logic.

Requirements and Context

Create:

docs/CLIENT_ERROR_HANDLING.md

Soroban failure model

Explain the distinct stages where a client can observe failure:

  • local transaction construction;
  • RPC/account loading;
  • simulateTransaction or transaction preparation;
  • submission response with an error status;
  • thrown SDK/RPC exception;
  • asynchronous transaction confirmation;
  • PayStream contract error;
  • nested token/router/oracle contract error;
  • Soroban host or authorization error.

Document that failures are not always thrown exceptions and may instead appear in structured simulation, submission, transaction-result, or diagnostic data.

Use HostError: Error(Contract, #N) as one possible representation, not as a guaranteed universal format.

Provenance and parsing

Do not teach clients to label every Error(Contract, #N) as PayStream. Nested contracts may reuse the same numeric codes.

The recommended process must:

  1. inspect structured SDK/RPC result fields first;
  2. inspect transaction result and diagnostic events where available;
  3. establish which contract emitted the error where possible;
  4. use string/regex extraction only as a tested fallback;
  5. preserve the raw error safely;
  6. return an unknown-contract/unknown-code result instead of guessing.

Explain that SDK error shapes may differ between simulation, submission, polling, and versions.

Complete JavaScript/TypeScript example

Include complete, runnable code using the version of @stellar/stellar-sdk actually pinned in keeper/package.json.

The example must demonstrate:

  • a read or simulated contract invocation;
  • a prepared state-changing transaction where appropriate;
  • checking simulation failure without submitting;
  • checking sendTransaction status rather than assuming failure always throws;
  • polling getTransaction to terminal status;
  • extracting a contract code from verified structured data where supported;
  • safe fallback parsing;
  • unknown-code handling;
  • preserving transaction hash;
  • distinguishing PayStream, nested-contract, host/auth, and RPC failures;
  • avoiding blind resubmission when the prior transaction may have succeeded;
  • redacting secrets and signatures;
  • large integer safety.

Do not include real secret keys. Use environment variables and obvious placeholders for public addresses only.

If a single snippet would become misleadingly large, provide one complete reusable parser plus smaller complete usage examples.

Validate exact class, namespace, status, and method names against the installed SDK version. Do not publish conceptual pseudocode as working client code.

UX response guidance

Provide a table mapping every catalogued PayStream error to:

  • user-facing message;
  • whether state should be refreshed;
  • whether subscriber, merchant, admin, or time-based action is required;
  • whether automatic retry is safe;
  • recommended next step.

At minimum, correct these cases:

  • PlanNotFound: verify network/contract/plan ID and refresh available plans.
  • PlanInactive: stop subscription submission and request a current active plan.
  • SubscriptionNotFound: verify contract/network/subscription ID.
  • SubscriptionNotActive: stop automatic charging or plan-change attempts.
  • NotYetDue: refetch subscription state and wait until the authoritative due time; do not tight-loop retries.
  • InsufficientAllowance: this is PayStream's internal allowance_remaining, not necessarily the token contract's live allowance. Do not promise that another token approve call alone will fix it.
  • Token allowance expired/insufficient: prompt a separate direct token-contract approval only when the failure is proven to originate from the token contract.
  • Unknown or ambiguous contract error: show a safe generic message, preserve diagnostics, and do not guess a remedy.

Include guidance for rejected user signatures, network failures, timeouts, expired transaction time bounds, and unknown confirmation status.

Simulation and preview functions

If dedicated simulate_charge() or simulate_subscribe() functions are actually merged when the guide is written:

  • document their exact ABI and limitations;
  • explain that preview state can become stale before submission;
  • do not imply simulation guarantees execution;
  • explain that simulation itself may be performed through Soroban RPC without dedicated contract preview functions.

If these functions are not merged, omit them or mark them clearly as planned—not available.

Retry safety

Explain:

  • permanent domain failures should not be retried unchanged;
  • NotYetDue is time-dependent;
  • transient RPC failures may be retried with bounded backoff;
  • a submitted transaction with unknown status must be checked by hash before rebuilding/resubmitting;
  • source-account sequence numbers and time bounds may require rebuilding after a confirmed failure;
  • clients must never log secret keys or signed envelopes.

Discoverability

Add relative links from:

  • docs/ARCHITECTURE.md
  • the README documentation section
  • docs/ERROR_CODES.md, if a cross-link improves navigation

Suggested Execution

  • Branch name: docs/client-error-handling-guide
  • Files to touch:
    • docs/CLIENT_ERROR_HANDLING.md
    • docs/ARCHITECTURE.md
    • README.md
    • docs/ERROR_CODES.md only for an optional cross-link
  • Example commit message: docs(errors): add client error handling guide with SDK examples

Test and Commit Steps

  1. Confirm docs(errors): build full error catalog reference #41 is merged and inspect the final catalog.
  2. Record the exact @stellar/stellar-sdk version from keeper/package.json.
  3. Inspect feat(keeper): add human-readable error messages for contract errors #42 if merged and reuse its proven extraction logic.
  4. Write the guide and complete examples.
  5. Extract code blocks into temporary files and validate them against installed dependencies:
Set-Location keeper
npm ci
node --check <temporary-example-path>

If TypeScript is used, run the repository's actual TypeScript checker or keep the primary example as executable JavaScript.

  1. Search for incorrect or stale error guidance:
Set-Location ..
rg "InsufficientAllowance|Error\(Contract|simulate_charge|simulate_subscribe" docs README.md keeper
  1. Verify files, links, and formatting:
Test-Path "docs/CLIENT_ERROR_HANDLING.md"
Select-String -Path "README.md","docs/ARCHITECTURE.md" -Pattern "CLIENT_ERROR_HANDLING.md"
git diff --check
  1. Commit with:
git add docs/CLIENT_ERROR_HANDLING.md docs/ARCHITECTURE.md README.md docs/ERROR_CODES.md
git commit -m "docs(errors): add client error handling guide with SDK examples"

Only stage docs/ERROR_CODES.md if it was changed.

Guidelines

  • Comment with confirmation that docs(errors): build full error catalog reference #41 is merged and the exact SDK version to request assignment.
  • Do not start or open a PR until assigned by a maintainer.
  • The PR description must include Closes #<issue-number>.
  • Keep the PR documentation-only.
  • Do not equate internal allowance with token-contract approval.
  • Do not label ambiguous nested-contract failures as PayStream errors.
  • Do not encourage blind retries of transactions with unknown status.
  • Document only APIs that are actually merged.
  • Never include or log secret keys.
  • Follow Conventional Commits and repository branch conventions.

Complexity

High (200 pts)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions