use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct OutcomeError {
pub kind: ErrorKind,
pub message: String,
pub compensation: Option<super::wait::CompensationAction>,
}
impl OutcomeError {
pub fn new(kind: ErrorKind, message: impl Into<String>) -> Self {
Self {
kind,
message: message.into(),
compensation: None,
}
}
pub fn with_compensation(mut self, action: super::wait::CompensationAction) -> Self {
self.compensation = Some(action);
self
}
pub fn is_retryable(&self) -> bool {
self.kind.is_retryable()
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum ErrorKind {
NotFound,
Conflict,
Validation,
PolicyRejection,
Cancelled,
StorageError,
Timeout,
Pending,
Serialization,
Internal,
BatchCollapse,
Custom(u16),
}
impl ErrorKind {
pub fn is_retryable(&self) -> bool {
matches!(self, Self::StorageError | Self::Timeout)
}
pub fn is_domain(&self) -> bool {
matches!(
self,
Self::NotFound
| Self::Conflict
| Self::Validation
| Self::PolicyRejection
| Self::Cancelled
)
}
pub fn is_operational(&self) -> bool {
matches!(
self,
Self::StorageError
| Self::Timeout
| Self::Pending
| Self::Serialization
| Self::Internal
| Self::BatchCollapse
)
}
}
impl fmt::Display for OutcomeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{:?}] {}", self.kind, self.message)
}
}
impl std::error::Error for OutcomeError {}