use runifold_core::{JournalError, RunError};
use thiserror::Error;
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum EffectExecutorErrorKind {
CapabilityDenied,
IdempotencyConflict,
Ambiguous,
Store,
Observability,
Handler,
Cancelled,
DeadlineExceeded,
Protocol,
Reconciliation,
}
#[derive(Clone, Debug, Error, PartialEq)]
#[error("{kind:?}: {message}")]
pub struct EffectExecutorError {
pub kind: EffectExecutorErrorKind,
pub message: String,
#[source]
pub source_error: Option<RunError>,
}
impl EffectExecutorError {
pub fn new(kind: EffectExecutorErrorKind, message: impl Into<String>) -> Self {
Self {
kind,
message: message.into(),
source_error: None,
}
}
pub(crate) fn handler(error: RunError) -> Self {
Self {
kind: EffectExecutorErrorKind::Handler,
message: error.to_string(),
source_error: Some(error),
}
}
pub(crate) fn reconciliation(error: RunError) -> Self {
Self {
kind: EffectExecutorErrorKind::Reconciliation,
message: error.to_string(),
source_error: Some(error),
}
}
pub(crate) fn ambiguous_handler(error: RunError) -> Self {
Self {
kind: EffectExecutorErrorKind::Ambiguous,
message: "effect handler failed after the remote outcome became uncertain".into(),
source_error: Some(error),
}
}
}
impl From<JournalError> for EffectExecutorError {
fn from(error: JournalError) -> Self {
Self::new(EffectExecutorErrorKind::Observability, error.to_string())
}
}