moghtech/komodo · error · anyhow::Error
{e:?}
Error message
{e:?} What it means
In the same async post helper, when the HTTP status is NOT success, the client reads the body as text and passes it to deserialize_error (extracting a server error message). If even that text extraction fails, the anyhow error {e:?} with the status attached is returned. Rare: means reading the response body itself failed.
Solutions
- Retry the request; the underlying network stream failed mid-response
- Check network path (proxy, LB) for premature connection closes
- Inspect server logs for the failing request to see the original error status
- Increase timeouts if the server is slow to produce error responses
Defensive patterns
Strategy: retry
Try / catch
for attempt in 0..3 {
match client.read(req.clone()).await {
Ok(r) => return Ok(r),
Err(e) if attempt < 2 && is_network_error(&e) => { tokio::time::sleep(delay).await; }
Err(e) => return Err(e),
}
} Prevention
- Add retry with backoff for transient body-read failures
- Check proxy/LB timeout settings
- Monitor connection resets on the client host
When it happens
Trigger: Non-2xx response where res.text().await fails — connection dropped mid-body, decompression error, or body streaming failure on an error response.
Common situations: Flaky networks or proxies closing the connection mid-error-response; server crashing while returning an error; timeouts truncating the body.
Related errors
AI-assisted analysis of moghtech/komodo@780ac68b99 (2026-09-08).
Data as JSON: /api/errors/f09148af08e24d72.
Report an issue: GitHub.
Appendix: source
Thrown at client/core/rs/src/request.rs:226
let req = self
.reqwest
.post(format!("{}{endpoint}", self.address))
.header("x-api-key", &self.key)
.header("x-api-secret", &self.secret)
.header("content-type", "application/json")
.json(&body);
let res =
req.send().await.context("failed to reach Komodo API")?;
let status = res.status();
if status.is_success() {
match res.json().await {
Ok(res) => Ok(res),
Err(e) => Err(anyhow!("{e:#?}").context(status)),
}
} else {
match res.text().await {
Ok(res) => Err(deserialize_error(res).context(status)),
Err(e) => Err(anyhow!("{e:?}").context(status)),
}
}
}
#[cfg(feature = "blocking")]
fn post<B: Serialize + std::fmt::Debug, R: DeserializeOwned>(
&self,
endpoint: &str,
body: B,
) -> anyhow::Result<R> {
let req = self
.reqwest
.post(format!("{}{endpoint}", self.address))
.header("x-api-key", &self.key)
.header("x-api-secret", &self.secret)
.header("content-type", "application/json")
.json(&body);
let res = req.send().context("failed to reach Komodo API")?;View on GitHub (pinned to 780ac68b99)