use crate::saga_action_generic::ActionData;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::fmt::Display;
use thiserror::Error;
#[derive(Clone, Debug, Deserialize, Error, JsonSchema, Serialize)]
pub enum ActionError {
#[error("action failed")]
ActionFailed { source_error: serde_json::Value },
#[error("deserialize failed: {message}")]
DeserializeFailed { message: String },
#[error("error injected")]
InjectedError,
#[error("serialize failed: {message}")]
SerializeFailed { message: String },
#[error("failed to create subsaga")]
SubsagaCreateFailed { message: String },
}
impl ActionError {
pub fn action_failed<E: ActionData>(user_error: E) -> ActionError {
match serde_json::to_value(user_error) {
Ok(source_error) => ActionError::ActionFailed { source_error },
Err(serialize_error) => ActionError::new_serialize(serialize_error),
}
}
pub fn convert<E: ActionData>(self) -> Result<E, ActionError> {
match self {
ActionError::ActionFailed { source_error } => {
serde_json::from_value(source_error)
.map_err(ActionError::new_deserialize)
}
_ => Err(self),
}
}
pub fn new_serialize(source: serde_json::Error) -> ActionError {
ActionError::SerializeFailed { message: source.to_string() }
}
pub fn new_deserialize<E: Display>(source: E) -> ActionError {
ActionError::DeserializeFailed { message: format!("{:#}", source) }
}
pub fn new_subsaga(source: anyhow::Error) -> ActionError {
let message = format!("{:#}", source);
ActionError::SubsagaCreateFailed { message }
}
}