use thiserror::Error;
#[derive(Error, Debug)]
pub enum LaneError {
#[error("Lane not found: {0}")]
LaneNotFound(String),
#[error("Queue error: {0}")]
QueueError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Command execution error: {0}")]
CommandError(String),
#[error("Job not found: {0}")]
JobNotFound(String),
#[error("Job state conflict: {0}")]
JobStateConflict(String),
#[error("Job lease conflict: {0}")]
JobLeaseConflict(String),
#[error("{0}")]
UnrecoverableJob(String),
#[error("Command timed out after {0:?}")]
Timeout(std::time::Duration),
#[error("Queue is shutting down, not accepting new commands")]
ShutdownInProgress,
#[error("{0}")]
Other(String),
}
pub type Result<T> = std::result::Result<T, LaneError>;
impl LaneError {
pub fn unrecoverable_job(message: impl Into<String>) -> Self {
Self::UnrecoverableJob(message.into())
}
pub fn is_unrecoverable_job(&self) -> bool {
matches!(self, Self::UnrecoverableJob(_))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lane_not_found_error() {
let error = LaneError::LaneNotFound("query".to_string());
assert_eq!(error.to_string(), "Lane not found: query");
}
#[test]
fn test_queue_error() {
let error = LaneError::QueueError("capacity exceeded".to_string());
assert_eq!(error.to_string(), "Queue error: capacity exceeded");
}
#[test]
fn test_config_error() {
let error = LaneError::ConfigError("invalid concurrency".to_string());
assert_eq!(
error.to_string(),
"Configuration error: invalid concurrency"
);
}
#[test]
fn test_command_error() {
let error = LaneError::CommandError("execution failed".to_string());
assert_eq!(
error.to_string(),
"Command execution error: execution failed"
);
}
#[test]
fn test_timeout_error() {
let error = LaneError::Timeout(std::time::Duration::from_secs(5));
assert_eq!(error.to_string(), "Command timed out after 5s");
}
#[test]
fn test_job_not_found_error() {
let error = LaneError::JobNotFound("job-1".to_string());
assert_eq!(error.to_string(), "Job not found: job-1");
}
#[test]
fn test_job_state_conflict_error() {
let error = LaneError::JobStateConflict("cannot complete waiting job".to_string());
assert_eq!(
error.to_string(),
"Job state conflict: cannot complete waiting job"
);
}
#[test]
fn test_job_lease_conflict_error() {
let error = LaneError::JobLeaseConflict("worker mismatch".to_string());
assert_eq!(error.to_string(), "Job lease conflict: worker mismatch");
}
#[test]
fn test_unrecoverable_job_error() {
let error = LaneError::unrecoverable_job("invalid customer state");
assert_eq!(error.to_string(), "invalid customer state");
assert!(error.is_unrecoverable_job());
}
#[test]
fn test_shutdown_in_progress_error() {
let error = LaneError::ShutdownInProgress;
assert_eq!(
error.to_string(),
"Queue is shutting down, not accepting new commands"
);
}
#[test]
fn test_other_error() {
let error = LaneError::Other("unexpected error".to_string());
assert_eq!(error.to_string(), "unexpected error");
}
#[test]
fn test_error_debug() {
let error = LaneError::LaneNotFound("test".to_string());
let debug_str = format!("{:?}", error);
assert!(debug_str.contains("LaneNotFound"));
}
}