use std::error::Error;
use std::fmt;
use super::CallbackError;
#[derive(Debug)]
pub enum ExecutorError<E> {
TaskFailed(E),
Panic(CallbackError),
PrepareFailed(CallbackError),
PrepareCommitFailed(CallbackError),
PrepareRollbackFailed {
original: CallbackError,
rollback: CallbackError,
},
}
impl<E> fmt::Display for ExecutorError<E>
where
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ExecutorError::TaskFailed(e) => {
write!(f, "Task execution failed: {}", e)
}
ExecutorError::Panic(error) => {
write!(f, "Execution panicked: {}", error)
}
ExecutorError::PrepareFailed(msg) => {
write!(f, "Preparation action failed: {}", msg)
}
ExecutorError::PrepareCommitFailed(msg) => {
write!(f, "Prepare commit action failed: {}", msg)
}
#[rustfmt::skip]
ExecutorError::PrepareRollbackFailed { original, rollback } => write!(f, "Prepare rollback failed: original error = {original}, rollback error = {rollback}"),
}
}
}
impl<E> ExecutorError<E> {
#[inline]
pub fn callback_type(&self) -> Option<&'static str> {
match self {
ExecutorError::TaskFailed(_) => None,
ExecutorError::Panic(error) => error.callback_type(),
ExecutorError::PrepareFailed(error) => error.callback_type(),
ExecutorError::PrepareCommitFailed(error) => error.callback_type(),
ExecutorError::PrepareRollbackFailed { original, rollback } => {
rollback.callback_type().or(original.callback_type())
}
}
}
}
impl<E> Error for ExecutorError<E>
where
E: Error + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
ExecutorError::TaskFailed(error) => Some(error),
ExecutorError::Panic(_) => None,
ExecutorError::PrepareFailed(_) => None,
ExecutorError::PrepareCommitFailed(_) => None,
ExecutorError::PrepareRollbackFailed { .. } => None,
}
}
}