use std::sync::Arc;
use std::time::Duration;
use thiserror::Error;
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum RuntimeError {
#[error("shutdown timeout {grace:?} exceeded; stuck: {stuck:?}; forcing termination")]
GraceExceeded {
grace: Duration,
stuck: Vec<Arc<str>>,
},
#[error("task '{name}' already exists in registry")]
TaskAlreadyExists {
name: Arc<str>,
},
#[error("task '{name}' not found in registry")]
TaskNotFound {
name: Arc<str>,
},
#[error("timeout waiting for task '{name}' removal after {timeout:?}")]
TaskRemoveTimeout {
name: Arc<str>,
timeout: Duration,
},
#[error("timeout waiting for task '{name}' registration after {timeout:?}")]
TaskAddTimeout {
name: Arc<str>,
timeout: Duration,
},
#[error("supervisor is shutting down")]
ShuttingDown,
}
impl RuntimeError {
pub fn as_label(&self) -> &'static str {
match self {
RuntimeError::GraceExceeded { .. } => "runtime_grace_exceeded",
RuntimeError::TaskAlreadyExists { .. } => "runtime_task_already_exists",
RuntimeError::TaskNotFound { .. } => "runtime_task_not_found",
RuntimeError::TaskRemoveTimeout { .. } => "runtime_task_remove_timeout",
RuntimeError::TaskAddTimeout { .. } => "runtime_task_add_timeout",
RuntimeError::ShuttingDown => "runtime_shutting_down",
}
}
}
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum TaskError {
#[error("timed out after {timeout:?}")]
Timeout { timeout: Duration },
#[error("fatal error (no retry): {reason}")]
Fatal { reason: String },
#[error("execution failed: {reason}")]
Fail { reason: String },
#[error("context canceled")]
Canceled,
}
impl TaskError {
pub fn as_label(&self) -> &'static str {
match self {
TaskError::Timeout { .. } => "task_timeout",
TaskError::Fatal { .. } => "task_fatal",
TaskError::Fail { .. } => "task_failed",
TaskError::Canceled => "task_canceled",
}
}
pub fn is_retryable(&self) -> bool {
matches!(self, TaskError::Timeout { .. } | TaskError::Fail { .. })
}
pub fn is_fatal(&self) -> bool {
matches!(self, TaskError::Fatal { .. })
}
}