Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cmd/crates/soroban-spec-tools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ impl Spec {
}
Err(Error::MissingErrorCase(value))
}

/// # Errors
///
/// Might return errors
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![no_std]
use soroban_sdk::{
contract, contracterror, contractimpl, contracttype, symbol_short, vec, Address, Bytes, BytesN,
Duration, Env, Map, String, Symbol, Timepoint, Val, Vec, I256, U256,
contract, contracterror, contractimpl, contracttype, panic_with_error, symbol_short, vec,
Address, Bytes, BytesN, Duration, Env, Map, String, Symbol, Timepoint, Val, Vec, I256, U256,
};

#[contract]
Expand Down Expand Up @@ -90,6 +90,14 @@ impl Contract {
}
}

pub fn panic_on_even(env: Env, u32_: u32) -> Result<u32, Error> {
if u32_ % 2 == 1 {
Ok(u32_)
} else {
panic_with_error!(&env, Error::NumberMustBeOdd)
}
}

pub fn u32_(_env: Env, u32_: u32) -> u32 {
u32_
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "test_error_caller"
version = "25.1.0"
authors = ["Stellar Development Foundation <info@stellar.org>"]
license = "Apache-2.0"
edition = "2021"
publish = false

[lib]
crate-type = ["cdylib", "rlib"]
doctest = false

[dependencies]
soroban-sdk = { workspace = true }

[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#![no_std]
use soroban_sdk::{
contract, contractclient, contracterror, contractimpl, panic_with_error, Address, Env, IntoVal,
InvokeError, Symbol,
};

/// Mirror of the inner contract's error enum.
/// Must match the error codes defined in custom_types contract.
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum InnerError {
/// Please provide an odd number
NumberMustBeOdd = 1,
}

/// Minimal client interface for the custom_types contract.
#[contractclient(name = "CustomTypesClient")]
pub trait CustomTypesInterface {
fn u32_fail_on_even(env: Env, u32_: u32) -> Result<u32, InnerError>;
}

#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum OuterError {
/// Caught inner error and remapped
RemappedInner = 10,
/// Uses the same error code as the inner contract
SameCodeAsInner = 1,
}

#[contract]
pub struct ErrorCallerContract;

#[contractimpl]
impl ErrorCallerContract {
/// Try-calls inner's u32_fail_on_even. Catches error, returns OuterError::RemappedInner.
pub fn catch_call(env: Env, inner: Address, u32_: u32) -> Result<u32, OuterError> {
match env.try_invoke_contract::<u32, InvokeError>(
&inner,
&Symbol::new(&env, "u32_fail_on_even"),
(u32_,).into_val(&env),
) {
Ok(Ok(val)) => Ok(val),
_ => Err(OuterError::RemappedInner),
}
}

/// Try-calls inner's u32_fail_on_even. Catches error and returns SameCodeAsInner.
pub fn catch_call_same_code(env: Env, inner: Address, u32_: u32) -> Result<u32, OuterError> {
match env.try_invoke_contract::<u32, InvokeError>(
&inner,
&Symbol::new(&env, "u32_fail_on_even"),
(u32_,).into_val(&env),
) {
Ok(Ok(val)) => Ok(val),
_ => Err(OuterError::SameCodeAsInner),
}
}

/// Try-calls inner via contractclient. Catches error, returns OuterError::RemappedInner.
pub fn catch_call_import(env: Env, inner: Address, u32_: u32) -> Result<u32, OuterError> {
let client = CustomTypesClient::new(&env, &inner);
match client.try_u32_fail_on_even(&u32_) {
Ok(Ok(val)) => Ok(val),
_ => Err(OuterError::RemappedInner),
}
}

/// Non-try call to inner's u32_fail_on_even. If inner fails, propagates as VM trap.
pub fn call(env: Env, inner: Address, u32_: u32) -> Result<u32, OuterError> {
Ok(env.invoke_contract(
&inner,
&Symbol::new(&env, "u32_fail_on_even"),
(u32_,).into_val(&env),
))
}

/// Non-try call to inner via contractclient. If inner fails, propagates as VM trap.
pub fn call_import(env: Env, inner: Address, u32_: u32) -> Result<u32, OuterError> {
let client = CustomTypesClient::new(&env, &inner);
Ok(client.u32_fail_on_even(&u32_))
}

/// Try-calls inner but returns non-Result type. Panics with error if inner fails.
/// Since this function doesn't return Result, the error shouldn't be resolved.
pub fn catch_panic_no_result(env: Env, inner: Address, u32_: u32) -> u32 {
let client = CustomTypesClient::new(&env, &inner);
match client.try_u32_fail_on_even(&u32_) {
Ok(Ok(val)) => val,
_ => panic_with_error!(&env, OuterError::RemappedInner),
}
}
}
1 change: 1 addition & 0 deletions cmd/crates/soroban-test/tests/it/integration.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod bindings;
mod constructor;
mod contract;
mod contract_errors;
mod cookbook;
mod custom_types;
mod dotenv;
Expand Down
Loading