Skip to content

SDK has no error-decoding layer mapping raw simulation/transaction failures to the KoraError enum #520

Description

@OxDev-max

Description

sdk/src/base.ts's invoke() method surfaces failures as raw, unstructured strings:

if (rpc.Api.isSimulationError(sim)) throw new Error(sim.error);
...
if (response.status === "ERROR") throw new Error(JSON.stringify(response.errorResult));

Meanwhile contracts/shared/src/errors.rs defines a rich, ~120-variant KoraError enum (e.g.
ProtocolPaused, InsufficientFunds, ExceedsFundingTarget, TokenNotWhitelisted,
FundingDeadlinePassed, etc.) that every contract returns as structured Result<_, KoraError>
failures. There is no TypeScript representation of this enum anywhere in sdk/, and no logic
that parses the numeric error code out of a Soroban contract-failure XDR/simulation error and
maps it back to a named variant. Every SDK consumer is left parsing ad-hoc stringified error
payloads to guess what actually went wrong.

Requirements and Context

This is a genuine cross-language integration gap between the Rust error taxonomy (the
authoritative source of truth) and the TypeScript client that's supposed to let external
consumers build against the protocol. Note this is different in kind from the documentation-only
docs/ERRORS.md gap (open issue #279) — this issue is about a programmatic, typed decoding
layer in the SDK itself, not documentation.

Suggested Execution

  1. git checkout -b feature/sdk-kora-error-decoding
  2. Generate (or hand-maintain, with a comment cross-referencing the source of truth) a
    TypeScript enum KoraError { Unauthorized = 1, NotAdmin = 2, ... } in sdk/src/errors.ts
    mirroring contracts/shared/src/errors.rs exactly, including the numeric discriminants.
  3. Add a decodeContractError(raw: unknown): KoraError | undefined helper that extracts the
    numeric error code from a Soroban simulation/transaction failure payload (the Error(#N)
    contract-error convention) and resolves it to the enum.
  4. Update BaseClient.invoke() to throw a typed KoraContractError (carrying both the decoded
    KoraError variant, when resolvable, and the raw payload as a fallback) instead of a bare
    Error.
  5. Add tests (per issue Add Tests for Invoice NFT Contracts #11) using representative captured simulation-failure payloads for a
    handful of variants (e.g. ProtocolPaused, InsufficientFunds) proving correct decoding.
  6. Cross-reference docs/ERRORS.md (issue Implement docs/ERRORS.md mapping every KoraError variant to cause and recommended handling #279, if/when completed) to keep the two in sync, but
    do not block this issue on that doc existing.

Acceptance Criteria

  • sdk/ contains a KoraError enum whose variants and numeric values exactly match contracts/shared/src/errors.rs
  • BaseClient.invoke() throws a typed error exposing the decoded KoraError variant when the failure payload contains a recognizable contract error code
  • A test proves at least 3 distinct error codes decode to their correct named variants
  • Unrecognized/unparseable failures still surface a usable error rather than throwing during decoding itself

Guidelines: PR description must include Closes #<issue-number>.
Complexity: High (200 points)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions