Skip to main content

spiral/scandal/
error.rs

1//! Errors that scandal operations return, as the scandal contract declares them.
2
3use spiral_contract::error::{ErrorEnvelope, new_error_instance_id};
4
5pub use super::api::ScandalError;
6
7impl ScandalError {
8    /// The error as the contract's envelope, for a transport that carries one.
9    pub fn to_wire(&self) -> ErrorEnvelope {
10        self.envelope(new_error_instance_id())
11    }
12
13    /// The declared error an envelope carries, or an internal error describing one it does not.
14    pub fn from_wire(envelope: &ErrorEnvelope) -> Self {
15        Self::decode_envelope(envelope).unwrap_or_else(|| Self::Internal {
16            message: envelope.to_string(),
17        })
18    }
19
20    /// The message a caller sees, whatever the error's kind.
21    pub fn message(&self) -> String {
22        match self {
23            Self::Unauthenticated { message }
24            | Self::InvalidArgument { message }
25            | Self::Conflict { message }
26            | Self::BudgetExceeded { message }
27            | Self::StorageUnavailable { message }
28            | Self::Unavailable { message }
29            | Self::Internal { message } => message.clone(),
30            Self::PermissionDenied {
31                operation,
32                resource,
33            } => format!("Permission `{operation}` denied on `{resource}`"),
34            Self::NotFound { resource } => format!("Resource `{resource}` not found"),
35        }
36    }
37}