#[derive(Debug, thiserror::Error)]
pub enum CheckerError {
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("invalid URL: {0}")]
InvalidUrl(String),
#[error("request timed out after {timeout_ms}ms")]
Timeout { timeout_ms: u64 },
#[error("connection refused: {0}")]
ConnectionRefused(String),
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
}
pub fn summarize_error(error: &reqwest::Error) -> String {
if error.is_timeout() {
return "Connection timed out".to_string();
}
if error.is_connect() {
let msg = error.to_string().to_lowercase();
if msg.contains("dns")
|| msg.contains("name or service not known")
|| msg.contains("nodename nor servname")
|| msg.contains("no such host")
|| msg.contains("getaddrinfo failed")
{
return "DNS resolution failed".to_string();
}
if msg.contains("ssl")
|| msg.contains("tls")
|| msg.contains("certificate")
|| msg.contains("handshake")
{
return "SSL/TLS error".to_string();
}
if msg.contains("connection refused") {
return "Connection refused".to_string();
}
return "Connection error".to_string();
}
if error.is_redirect() {
return "Redirect loop".to_string();
}
let msg = error.to_string();
if msg.len() > 80 {
format!("{}...", &msg[..77])
} else {
msg
}
}
pub fn summarize_error_str(msg: &str) -> &'static str {
let lower = msg.to_lowercase();
if lower.contains("timed out") || lower.contains("timeout") {
return "Connection timed out";
}
if lower.contains("dns")
|| lower.contains("name or service not known")
|| lower.contains("getaddrinfo")
{
return "DNS resolution failed";
}
if lower.contains("ssl") || lower.contains("tls") || lower.contains("certificate") {
return "SSL/TLS error";
}
if lower.contains("connection refused") {
return "Connection refused";
}
if lower.contains("redirect") {
return "Redirect loop";
}
"Connection error"
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn summarize_timeout_string() {
assert_eq!(
summarize_error_str("request timed out after 10000ms"),
"Connection timed out"
);
}
#[test]
fn summarize_dns_string() {
assert_eq!(
summarize_error_str("DNS resolution failed for host"),
"DNS resolution failed"
);
}
#[test]
fn summarize_ssl_string() {
assert_eq!(summarize_error_str("SSL handshake error"), "SSL/TLS error");
}
#[test]
fn summarize_refused_string() {
assert_eq!(
summarize_error_str("Connection refused on port 8080"),
"Connection refused"
);
}
#[test]
fn summarize_redirect_string() {
assert_eq!(summarize_error_str("too many redirects"), "Redirect loop");
}
#[test]
fn summarize_unknown_string() {
assert_eq!(
summarize_error_str("some other failure"),
"Connection error"
);
}
}