crispy_stream_checker/
error.rs1#[derive(Debug, thiserror::Error)]
5pub enum CheckerError {
6 #[error("HTTP error: {0}")]
8 Http(#[from] reqwest::Error),
9
10 #[error("invalid URL: {0}")]
12 InvalidUrl(String),
13
14 #[error("request timed out after {timeout_ms}ms")]
16 Timeout { timeout_ms: u64 },
17
18 #[error("connection refused: {0}")]
20 ConnectionRefused(String),
21
22 #[error("I/O error: {0}")]
24 Io(#[from] std::io::Error),
25}
26
27pub fn summarize_error(error: &reqwest::Error) -> String {
49 if error.is_timeout() {
50 return "Connection timed out".to_string();
51 }
52
53 if error.is_connect() {
54 let msg = error.to_string().to_lowercase();
55
56 if msg.contains("dns")
57 || msg.contains("name or service not known")
58 || msg.contains("nodename nor servname")
59 || msg.contains("no such host")
60 || msg.contains("getaddrinfo failed")
61 {
62 return "DNS resolution failed".to_string();
63 }
64
65 if msg.contains("ssl")
66 || msg.contains("tls")
67 || msg.contains("certificate")
68 || msg.contains("handshake")
69 {
70 return "SSL/TLS error".to_string();
71 }
72
73 if msg.contains("connection refused") {
74 return "Connection refused".to_string();
75 }
76
77 return "Connection error".to_string();
78 }
79
80 if error.is_redirect() {
81 return "Redirect loop".to_string();
82 }
83
84 let msg = error.to_string();
86 if msg.len() > 80 {
87 format!("{}...", &msg[..77])
88 } else {
89 msg
90 }
91}
92
93pub fn summarize_error_str(msg: &str) -> &'static str {
97 let lower = msg.to_lowercase();
98
99 if lower.contains("timed out") || lower.contains("timeout") {
100 return "Connection timed out";
101 }
102 if lower.contains("dns")
103 || lower.contains("name or service not known")
104 || lower.contains("getaddrinfo")
105 {
106 return "DNS resolution failed";
107 }
108 if lower.contains("ssl") || lower.contains("tls") || lower.contains("certificate") {
109 return "SSL/TLS error";
110 }
111 if lower.contains("connection refused") {
112 return "Connection refused";
113 }
114 if lower.contains("redirect") {
115 return "Redirect loop";
116 }
117 "Connection error"
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn summarize_timeout_string() {
126 assert_eq!(
127 summarize_error_str("request timed out after 10000ms"),
128 "Connection timed out"
129 );
130 }
131
132 #[test]
133 fn summarize_dns_string() {
134 assert_eq!(
135 summarize_error_str("DNS resolution failed for host"),
136 "DNS resolution failed"
137 );
138 }
139
140 #[test]
141 fn summarize_ssl_string() {
142 assert_eq!(summarize_error_str("SSL handshake error"), "SSL/TLS error");
143 }
144
145 #[test]
146 fn summarize_refused_string() {
147 assert_eq!(
148 summarize_error_str("Connection refused on port 8080"),
149 "Connection refused"
150 );
151 }
152
153 #[test]
154 fn summarize_redirect_string() {
155 assert_eq!(summarize_error_str("too many redirects"), "Redirect loop");
156 }
157
158 #[test]
159 fn summarize_unknown_string() {
160 assert_eq!(
161 summarize_error_str("some other failure"),
162 "Connection error"
163 );
164 }
165}