{"record":{"id":"ef6cc6b66f5e6162","repo":"Hmbown/CodeWhale","slug":"connection-degraded-failures","errorCode":null,"errorMessage":"Connection degraded (failures={}): {}","messagePattern":"Connection degraded \\(failures=(.+?)\\): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":2534,"sourceCode":"            let mut limiter = self.rate_limiter.lock().await;\n            limiter.delay_until_available(1.0)\n        };\n        if let Some(delay) = maybe_delay {\n            tokio::time::sleep(delay).await;\n        }\n    }\n\n    async fn mark_request_success(&self) {\n        let mut health = self.connection_health.lock().await;\n        if apply_request_success(&mut health, Instant::now()) {\n            logging::info(\"Connection recovered\");\n        }\n    }\n\n    async fn mark_request_failure(&self, reason: &str) {\n        let mut health = self.connection_health.lock().await;\n        apply_request_failure(&mut health, Instant::now());\n        logging::warn(format!(\n            \"Connection degraded (failures={}): {}\",\n            health.consecutive_failures, reason\n        ));\n    }\n\n    async fn maybe_probe_recovery(&self) {\n        let should_probe = {\n            let mut health = self.connection_health.lock().await;\n            mark_recovery_probe_if_due(&mut health, Instant::now())\n        };\n        if !should_probe {\n            return;\n        }\n        if api_provider_skips_models_probe(self.api_provider) {\n            self.mark_request_success().await;\n            logging::info(\"Skipping /models recovery probe for provider without a models endpoint\");\n            return;\n        }","sourceCodeStart":2516,"sourceCodeEnd":2552,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/client.rs#L2516-L2552","documentation":"mark_request_failure records the failure in connection_health; when the failure count crosses the degradation threshold, the client logs \"Connection degraded (failures=N): reason\" and the rate limiter backs off subsequent requests with increasing delay. It is an adaptive health signal for repeated request failures (network errors, 5xx, timeouts) — recovery is logged separately by mark_request_success.","triggerScenarios":"Thrown at crates/tui/src/client.rs:2534 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Read the trailing reason to identify the failing request class (timeout, connect, HTTP status)","Wait for the rate limiter backoff; requests resume automatically after delays elapse","Check endpoint reachability/credentials if failures keep accumulating; recovery is logged as 'Connection recovered'"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}