oasis_contract_sdk/
error.rs

1//! Contract error trait.
2use crate::types::ExecutionResult;
3
4/// A contract error that gets propagated to the caller.
5///
6/// It extends `std::error::Error` with module name and error code so that errors can be easily
7/// serialized and transferred between different processes.
8///
9/// This trait can be derived:
10/// ```
11/// # #[cfg(feature = "oasis-contract-sdk-macros")]
12/// # mod example {
13/// # use oasis_contract_sdk_macros::Error;
14/// #[derive(Clone, Debug, Error, thiserror::Error)]
15/// #[sdk_error(autonumber)]
16/// enum Error {
17///    #[error("invalid argument")]
18///    InvalidArgument,          // autonumbered to 0
19///
20///    #[error("forbidden")]
21///    #[sdk_error(code = 401)]  // manually numbered to 403 (`code` or autonumbering is required)
22///    Forbidden,
23/// }
24/// # }
25/// ```
26pub trait Error: std::error::Error {
27    /// Name of the module that emitted the error.
28    fn module_name(&self) -> &str;
29
30    /// Error code uniquely identifying the error.
31    fn code(&self) -> u32;
32
33    /// Converts the error into an execution result.
34    fn to_execution_result(&self) -> ExecutionResult {
35        ExecutionResult::Failed {
36            module: self.module_name().to_owned(),
37            code: self.code(),
38            message: self.to_string(),
39        }
40    }
41}
42
43impl Error for std::convert::Infallible {
44    fn module_name(&self) -> &str {
45        "(none)"
46    }
47
48    fn code(&self) -> u32 {
49        Default::default()
50    }
51}