use anyhow::Error as AnyhowError;
use std::time::Duration;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum OrkaError {
#[error("Step not found: {step_name}")]
StepNotFound { step_name: String },
#[error("Handler missing for non-optional step: {step_name}")]
HandlerMissing { step_name: String },
#[error("Extractor failed for step '{step_name}'. Source: {source}")]
ExtractorFailure {
step_name: String,
#[source]
source: AnyhowError,
},
#[error("Pipeline provider failed for conditional scope in step '{step_name}'. Source: {source}")]
PipelineProviderFailure {
step_name: String,
#[source]
source: AnyhowError,
},
#[error("Type mismatch during context downcast (expected {expected_type}, step: '{step_name}')")]
TypeMismatch {
step_name: String,
expected_type: String,
},
#[error("Error in user-provided handler or external operation. Source: {source}")]
HandlerError {
#[source]
source: AnyhowError,
},
#[error("Configuration error for step '{step_name}': {message}")]
ConfigurationError { step_name: String, message: String },
#[error("Internal Orka error: {0}")]
Internal(String),
#[error("No conditional scope's condition matched for step '{step_name}'")]
NoConditionalScopeMatched { step_name: String },
#[error(
"Fan-out policy {policy} unmet: {succeeded} of {total} succeeded ({failed} failed, {not_started} never started)"
)]
FanOutPolicyUnmet {
policy: String,
total: usize,
succeeded: usize,
failed: usize,
not_started: usize,
},
#[error("Fan-out branch {index} did not run to completion (its task panicked or was aborted)")]
FanOutBranchLost { index: usize },
#[error("Required resource '{resource}' is not present in the context (was its producing step skipped or removed?)")]
ResourceMissing { resource: String },
#[error("Step '{step_name}' timed out after {after:?}")]
StepTimedOut { step_name: String, after: Duration },
}
impl From<AnyhowError> for OrkaError {
fn from(err: AnyhowError) -> Self {
OrkaError::HandlerError { source: err }
}
}
pub type OrkaResult<T, E = OrkaError> = std::result::Result<T, E>;