Skip to content

Commit b836970

Browse files
Merge pull request #170 from stellar/issue-agent/163-try-result-nesting
Fix the try_ result nesting in the smart-contracts skill
2 parents c50f7d8 + 51d88e0 commit b836970

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"skills": [
3+
"smart-contracts"
4+
],
5+
"query": "My Stellar contract returns Result<(), ContractError>. Write a unit test that checks transfer fails with InvalidAmount when the amount is zero.",
6+
"expected_behavior": [
7+
"Calls the generated try_transfer method rather than transfer, which panics on error",
8+
"Matches the contract's typed error as Err(Ok(ContractError::InvalidAmount)), not Ok(Err(...))",
9+
"Does not describe Err(Err(_)) as the typed contract error: it is an InvokeError from a panic, a host failure, or an error code the enum does not define"
10+
],
11+
"machine_checkable": [
12+
"Generated test module compiles and passes: cargo test"
13+
]
14+
}

‎skills/smart-contracts/development.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ pub fn transfer(env: Env, from: Address, to: Address, amount: i128) -> Result<()
284284
}
285285
```
286286

287-
- Returning `Result` gives callers typed errors: generated clients expose both `foo()` (panics on error) and `try_foo()` returning `Result<Result<T, E>, InvokeError>` — `Ok(Err(e))` is your typed error, outer `Err` is a host-level failure (budget, bad auth, type mismatch).
287+
- Returning `Result` gives callers typed errors: generated clients expose both `foo()` (panics on error) and `try_foo()` returning `Result<Result<T, _>, Result<E, InvokeError>>`. `Err(Ok(e))` is your typed error. `Err(Err(_))` is an `InvokeError`: a panic or host-level failure (bad auth, type mismatch), or an error code your `E` does not define. `Ok(Err(_))` means the return value failed to convert to `T`. If `foo` does not return `Result`, `E` is `soroban_sdk::Error`, so host failures arrive as `Err(Ok(_))`. Budget exhaustion and footprint violations are not recoverable, so `try_` cannot catch them. In tests: `assert_eq!(client.try_transfer(&from, &to, &0), Err(Ok(ContractError::InvalidAmount)));`
288288
- When panicking, use `panic_with_error!(&env, Error::X)`, not bare `panic!("msg")` — bare panics surface as opaque host errors clients can't match on.
289289
- Error codes are public ABI. Never renumber across upgrades.
290290
- An `Err` return or panic rolls back **all** state changes of the invocation, including nested calls' writes.

0 commit comments

Comments
 (0)