True when a `ureq` error is a connection-level failure that a freshly started (or briefly overloaded) server can transiently raise before it is steadily accepting requests: peer disconnected, connection refused/reset, or a bare I/O error. These are safe to retry for idempotent test requests; an HTTP status error is NOT one of these (the agent is built with `http_status_as_error(false)`, so 4xx/5xx
(err: &ureq::Error)
| 508 | /// an HTTP status error is NOT one of these (the agent is built with |
| 509 | /// `http_status_as_error(false)`, so 4xx/5xx come back as `Ok`). |
| 510 | pub fn is_transient_connection_error(err: &ureq::Error) -> bool { |
| 511 | match err { |
| 512 | ureq::Error::ConnectionFailed => true, |
| 513 | ureq::Error::Io(_) => true, |
| 514 | other => { |
| 515 | // Fall back to a message match so newer/renamed variants (e.g. |
| 516 | // "Peer disconnected", "connection reset") still count as transient |
| 517 | // without pinning to a specific ureq version's enum shape. |
| 518 | let text = other.to_string().to_ascii_lowercase(); |
| 519 | text.contains("peer disconnected") |
| 520 | || text.contains("connection refused") |
| 521 | || text.contains("connection reset") |
| 522 | || text.contains("broken pipe") |
| 523 | || text.contains("timed out") |
| 524 | } |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | /// Issues an idempotent HTTP request, retrying transient connection-level |
| 529 | /// errors (the server racing its own readiness under parallel load) with a |
no test coverage detected