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

  1. Retry the request; the underlying network stream failed mid-response
  2. Check network path (proxy, LB) for premature connection closes
  3. Inspect server logs for the failing request to see the original error status
  4. 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

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)