Hmbown/CodeWhale · error · io::Error

Shared pet connection failed

Error message

Shared pet connection failed

What it means

This io::Error is returned by the shared-pet HTTP client in pet_watch/live.rs when the server responds with a non-success status. It carries the server's `error` message string (falling back to the generic text), and maps a 409 CONFLICT whose message does not mention 'storage' to ErrorKind::InvalidInput; all other failures map to ErrorKind::Other.

Solutions

  1. Read the error's message: it is the server's `error` field — fix the condition it names (e.g. retry later on a storage-related 409 conflict).
  2. Check connectivity/availability of the shared pet service before or after failure.
  3. Retry with backoff for transient 5xx; treat ErrorKind::InvalidInput (409 non-storage) as a request problem, not a retry.
  4. Fall back to local-only pet state when the shared connection fails.

Example fix

// before
let pet = shared.get(pet_id)?;
// after
let pet = match shared.get(pet_id) {
    Ok(p) => p,
    Err(e) if e.kind() == io::ErrorKind::Other => { log::warn!("shared pet unavailable: {e}"); local_pet() }
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Validate before calling

// optionally probe first
let healthy = shared.get(health_path).is_ok();

Try / catch

match shared.post(url, &body) {
    Err(e) if e.kind() == io::ErrorKind::Other => retry_with_backoff(),
    Err(e) => return Err(e),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: Any request through the shared-pet API (request(), used by runner_request, public_request, get, post) that gets resp.success() == false — e.g. 409 conflict on concurrent pet updates, 4xx/5xx from the shared pet backend.

Common situations: Two clients writing the same shared pet state concurrently (409), shared-pet service outage returning 500, auth/permission rejection from the remote endpoint, offline network yielding a gateway error.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/bbcdad0cba183681. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/pet_watch/live.rs:222

            .map_err(io::Error::other)?;
        let status = response.status();
        let success = status.is_success();
        let bound = if path == "/v1/export" {
            super::persistence::MAX_EXPORT_BYTES
        } else {
            8 * 1024 * 1024
        };
        let mut bytes = Vec::new();
        response.take(bound as u64 + 1).read_to_end(&mut bytes)?;
        if bytes.len() > bound {
            return Err(io::Error::other("Pet response exceeds its bound"));
        }
        let value: Value = serde_json::from_slice(&bytes)?;
        if !success {
            let message = value["error"]
                .as_str()
                .unwrap_or("Shared pet connection failed");
            return Err(io::Error::new(
                if status == reqwest::StatusCode::CONFLICT && !message.contains("storage") {
                    io::ErrorKind::InvalidInput
                } else {
                    io::ErrorKind::Other
                },
                message,
            ));
        }
        Ok(value)
    }
    pub fn open_browser(&self) -> io::Result<()> {
        let url = format!(
            "http://127.0.0.1:{}/#{}",
            self.descriptor.port, self.descriptor.token
        );
        webbrowser::open(&url).map_err(io::Error::other)
    }
    pub fn open_window(&self) -> io::Result<()> {

View on GitHub (pinned to 73e0f67d83)