use std::fmt;
use std::time::Duration;
#[derive(Debug)]
pub enum ScatterProxyError {
Timeout { elapsed: Duration },
PoolFull { capacity: usize },
Init(String),
UnknownHost(String),
}
impl fmt::Display for ScatterProxyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ScatterProxyError::Timeout { elapsed } => {
write!(f, "task timeout after {:.1}s", elapsed.as_secs_f64())
}
ScatterProxyError::PoolFull { capacity } => {
write!(f, "task pool is full (capacity: {capacity})")
}
ScatterProxyError::Init(reason) => {
write!(f, "initialization error: {reason}")
}
ScatterProxyError::UnknownHost(host) => {
write!(f, "host not registered in router: {host}")
}
}
}
}
impl std::error::Error for ScatterProxyError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_timeout() {
let err = ScatterProxyError::Timeout {
elapsed: Duration::from_millis(8500),
};
let msg = err.to_string();
assert!(msg.contains("8.5s"));
}
#[test]
fn display_pool_full() {
let err = ScatterProxyError::PoolFull { capacity: 1000 };
let msg = err.to_string();
assert!(msg.contains("task pool is full"));
assert!(msg.contains("1000"));
}
#[test]
fn display_init() {
let err = ScatterProxyError::Init("failed to fetch proxy list".into());
let msg = err.to_string();
assert!(msg.contains("initialization error"));
assert!(msg.contains("failed to fetch proxy list"));
}
#[test]
fn error_trait_is_implemented() {
let err: Box<dyn std::error::Error> = Box::new(ScatterProxyError::Init("test".into()));
assert!(err.source().is_none());
}
#[test]
fn display_unknown_host() {
let err = ScatterProxyError::UnknownHost("szse.cn".into());
let msg = err.to_string();
assert!(msg.contains("szse.cn"));
assert!(msg.contains("not registered"));
}
#[test]
fn debug_format_includes_variant_name() {
let err = ScatterProxyError::Timeout {
elapsed: Duration::from_secs(1),
};
let dbg = format!("{err:?}");
assert!(dbg.contains("Timeout"));
}
#[test]
fn timeout_sub_second_formatting() {
let err = ScatterProxyError::Timeout {
elapsed: Duration::from_millis(200),
};
assert!(err.to_string().contains("0.2s"));
}
#[test]
fn timeout_exact_seconds_formatting() {
let err = ScatterProxyError::Timeout {
elapsed: Duration::from_secs(60),
};
assert!(err.to_string().contains("60.0s"));
}
}