diff options
| -rw-r--r-- | src/sync/naughty_list.rs | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/src/sync/naughty_list.rs b/src/sync/naughty_list.rs index 35fcc0f..097affe 100644 --- a/src/sync/naughty_list.rs +++ b/src/sync/naughty_list.rs | |||
| @@ -114,11 +114,15 @@ impl NaughtyListTracker { | |||
| 114 | pub fn classify_error(error: &str) -> Option<NaughtyCategory> { | 114 | pub fn classify_error(error: &str) -> Option<NaughtyCategory> { |
| 115 | let error_lower = error.to_lowercase(); | 115 | let error_lower = error.to_lowercase(); |
| 116 | 116 | ||
| 117 | // DNS lookup failures | 117 | // DNS lookup failures - use specific patterns to avoid false positives |
| 118 | // from URLs containing "dns" (e.g., npubs like "...cdns7..." or domains) | ||
| 118 | if error_lower.contains("failed to lookup address") | 119 | if error_lower.contains("failed to lookup address") |
| 119 | || error_lower.contains("name or service not known") | 120 | || error_lower.contains("name or service not known") |
| 120 | || error_lower.contains("nodename nor servname provided") | 121 | || error_lower.contains("nodename nor servname provided") |
| 121 | || (error_lower.contains("dns") && !error_lower.contains("timeout")) | 122 | || error_lower.contains("dns error") |
| 123 | || error_lower.contains("dns lookup") | ||
| 124 | || error_lower.contains("dns resolution") | ||
| 125 | || error_lower.contains("getaddrinfo") | ||
| 122 | { | 126 | { |
| 123 | return Some(NaughtyCategory::DnsLookupFailed); | 127 | return Some(NaughtyCategory::DnsLookupFailed); |
| 124 | } | 128 | } |
| @@ -373,6 +377,34 @@ mod tests { | |||
| 373 | NaughtyListTracker::classify_error("network unreachable"), | 377 | NaughtyListTracker::classify_error("network unreachable"), |
| 374 | None | 378 | None |
| 375 | ); | 379 | ); |
| 380 | |||
| 381 | // Repository not found is transient (not an infrastructure issue) | ||
| 382 | assert_eq!( | ||
| 383 | NaughtyListTracker::classify_error( | ||
| 384 | "fatal: repository 'https://example.com/repo.git/' not found" | ||
| 385 | ), | ||
| 386 | None | ||
| 387 | ); | ||
| 388 | } | ||
| 389 | |||
| 390 | #[test] | ||
| 391 | fn test_classify_false_positive_npub_with_dns() { | ||
| 392 | // This npub contains "dns" in its encoding: npub17plqkxhsv66g8quxxc9p5t9mxazzn20m426exqnl8lxnh5a4cDNS7jezx0 | ||
| 393 | // A "not found" error with this npub should NOT be classified as DNS failure | ||
| 394 | let error = "fatal: repository 'https://git.shakespeare.diy/npub17plqkxhsv66g8quxxc9p5t9mxazzn20m426exqnl8lxnh5a4cdns7jezx0/kuboslopp%20by%20Shakespeare.git/' not found"; | ||
| 395 | assert_eq!( | ||
| 396 | NaughtyListTracker::classify_error(error), | ||
| 397 | None, | ||
| 398 | "npub containing 'dns' should not trigger DNS failure classification" | ||
| 399 | ); | ||
| 400 | |||
| 401 | // Same for relay.ngit.dev | ||
| 402 | let error2 = "fatal: repository 'https://relay.ngit.dev/npub17plqkxhsv66g8quxxc9p5t9mxazzn20m426exqnl8lxnh5a4cdns7jezx0/kuboslopp%20by%20Shakespeare.git/' not found"; | ||
| 403 | assert_eq!( | ||
| 404 | NaughtyListTracker::classify_error(error2), | ||
| 405 | None, | ||
| 406 | "npub containing 'dns' should not trigger DNS failure classification" | ||
| 407 | ); | ||
| 376 | } | 408 | } |
| 377 | 409 | ||
| 378 | #[test] | 410 | #[test] |