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}