Skip to content

fix(escrow): typed EscrowNotFound error instead of .expect() panics - #542

Open
Vyacheslav-Tomashevskiy wants to merge 1 commit into
Northgate-Systems:mainfrom
Vyacheslav-Tomashevskiy:fix/332-escrow-not-found-error
Open

fix(escrow): typed EscrowNotFound error instead of .expect() panics#542
Vyacheslav-Tomashevskiy wants to merge 1 commit into
Northgate-Systems:mainfrom
Vyacheslav-Tomashevskiy:fix/332-escrow-not-found-error

Conversation

@Vyacheslav-Tomashevskiy

@Vyacheslav-Tomashevskiy Vyacheslav-Tomashevskiy commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

get_escrow(), release(), and refund() all used .expect("Escrow not found") when looking up a nonexistent escrow_id, which panics with an untyped, unstructured message. This adds a soroban_sdk::contracterror Error enum with an EscrowNotFound variant and changes the three functions to return Result<T, Error>.

Scope note: this only covers the not-found case from #332. The other panic!() calls in this module (bad amount, wrong status, not-yet-expired) are intentionally left untouched — covering every failure mode with typed errors is the broader scope of #333, and mixing the two would make this PR harder to review.

What changed

  • contracts/escrow/src/lib.rs: added Error enum (#[contracterror]), changed get_escrow/release/refund signatures to Result<T, Error>, replaced .expect("Escrow not found") with .ok_or(Error::EscrowNotFound)/?.
  • contracts/escrow/src/test.rs: replaced the two #[should_panic(expected = "Escrow not found")] tests with typed-error assertions via the generated try_release/try_refund/try_get_escrow client methods, and added a test confirming the non-try_ get_escrow() still returns the state directly on the success path.
  • contracts/escrow/README.md: updated the interface table + a short note on the new error type.

The Soroban SDK's #[contractimpl] macro auto-generates both a panicking foo() client method (unchanged behavior on the happy path) and a try_foo() method returning the typed Result for any function returning Result<T, Error>, so this is not a breaking change for existing callers that only used the non-try_ methods and never inspected the panic message text.

Testing

  • cargo test: 15/15 pass (13 pre-existing + 2 new: test_get_escrow_nonexistent_returns_typed_error, test_get_escrow_found_still_returns_state_directly; the two not-found tests for release/refund were converted rather than added, so net +1 test file count but the two should_panic string-matching tests became explicit typed-error matches).
  • cargo clippy --all-targets -- -D warnings: clean, no warnings.
  • cargo fmt --check: shows the same 7 pre-existing diffs that are already on a clean main checkout (verified by running cargo fmt --check on main before making any changes) — none of them touch code this PR modifies, so I left them alone rather than reformatting unrelated lines.
  • cargo build --target wasm32-unknown-unknown --release: fails identically on this branch and on a clean main checkout (soroban-sdk's testutils feature is pulled in as a normal dependency in Cargo.toml, which has a hard compile_error! on the wasm32 target). Pre-existing, unrelated to this change — already flagged to the maintainer in the Support multiple concurrent escrows per sender/recipient pair #342 (escrow IDs) PR thread.

Checklist (from the issue)

  • Behavior implemented in contracts/escrow/src/lib.rs
  • New/updated tests in contracts/escrow/src/test.rs covering success and failure paths
  • cargo test passes locally
  • cargo clippy -- -D warnings and cargo fmt --check pass (fmt: no new diffs introduced, see above)
  • Doc comments updated
  • README.md updated (interface table + error-handling note)

Closes #332

get_escrow(), release(), and refund() all used
.expect("Escrow not found") when looking up a nonexistent escrow_id,
which panics with an untyped, unstructured message that callers can't
match on programmatically.

Added a soroban_sdk::contracterror Error enum with an EscrowNotFound
variant and changed the three functions to return
Result<T, Error>/Result<(), Error>. The generated client keeps the
existing panicking foo() methods for the happy path plus adds
try_foo() methods that return the typed error, so callers that want
to handle a missing escrow gracefully now can.

Scope: only the not-found case from issue Northgate-Systems#332. The other panic!()
calls in this module (bad amount, wrong status, not-yet-expired) are
left untouched -- covering every failure mode is the broader, separate
scope of issue Northgate-Systems#333.

Tests: replaced the two should_panic(expected = "Escrow not found")
tests with typed-error assertions via try_release/try_refund/
try_get_escrow, and added a test confirming the non-try get_escrow()
still returns the state directly on the success path. 15/15 tests
pass (13 pre-existing + 2 new). cargo clippy --all-targets -- -D
warnings is clean. cargo fmt --check shows the same 7 pre-existing
diffs that are already on main (unrelated formatting, not touched by
this change) -- confirmed by running fmt --check on a clean checkout
of main before making any changes.

cargo build --target wasm32-unknown-unknown --release still fails on
this branch the same way it fails on a clean main checkout (Cargo.toml
pulls in soroban-sdk's "testutils" feature as a normal dependency,
which has a hard compile_error! on the wasm target) -- pre-existing,
unrelated to this fix, already flagged to the maintainer in the Northgate-Systems#341
escrow-ids PR.

Closes Northgate-Systems#332
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the codex723's projects Team on Vercel.

A member of the Team first needs to authorize it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add get_escrow not-found error handling instead of .expect()

1 participant