googleworkspace/cli · error · GwsError

Failed to list calendars: {e}

Error message

Failed to list calendars: {e}

What it means

The +calendar helper's first step is a plain GET of https://www.googleapis.com/calendar/v3/users/me/calendarList. This error wraps only the transport-level failure of that request (reqwest send error): DNS resolution, TCP connect, TLS handshake, proxy refusal, or cancellation — anything before an HTTP status exists. HTTP error statuses are handled separately as GwsError::Api with reason calendarList_failed.

Source

Thrown at crates/google-workspace-cli/src/helpers/calendar.rs:268

        // From now, N days ahead
        let end = now_in_tz + chrono::Duration::days(days);
        (now_in_tz, end)
    };

    let time_min = time_min_dt.to_rfc3339();
    let time_max = time_max_dt.to_rfc3339();

    // client already built above for timezone resolution
    let calendar_filter = matches.get_one::<String>("calendar");

    // 1. List all calendars
    let list_url = "https://www.googleapis.com/calendar/v3/users/me/calendarList";
    let list_resp = client
        .get(list_url)
        .bearer_auth(&token)
        .send()
        .await
        .map_err(|e| GwsError::Other(anyhow::anyhow!("Failed to list calendars: {e}")))?;

    if !list_resp.status().is_success() {
        let err = list_resp.text().await.unwrap_or_default();
        return Err(GwsError::Api {
            code: 0,
            message: err,
            reason: "calendarList_failed".to_string(),
            enable_url: None,
        });
    }

    let list_json: Value = list_resp
        .json()
        .await
        .map_err(|e| GwsError::Other(anyhow::anyhow!("Failed to parse calendar list: {e}")))?;

    let calendars = list_json
        .get("items")

View on GitHub (pinned to a3768d0e82)

Solutions

  1. Check basic reachability: curl -sv https://www.googleapis.com/calendar/v3/users/me/calendarList
  2. Verify HTTP_PROXY/HTTPS_PROXY/NO_PROXY values match the current network
  3. Fix DNS/firewall/VPN, then retry — transport failures are transient by nature
Defensive patterns

Strategy: retry

Validate before calling

// Cheap reachability probe before the helper run
async fn googleapi_reachable() -> bool {
    reqwest::get("https://www.googleapis.com").await.is_ok()
}

Try / catch

let mut attempt = 0;
loop {
    match list_calendars(&client, &token).await {
        Ok(cals) => break cals,
        Err(e) if e.to_string().contains("Failed to list calendars") && attempt < 3 => {
            attempt += 1;
            tokio::time::sleep(std::time::Duration::from_secs(2u64.pow(attempt))).await;
        }
        Err(e) => return Err(e), // DNS/proxy config problems will not heal — stop and report
    }
}

Prevention

When it happens

Trigger: No network / DNS failure for www.googleapis.com; HTTPS_PROXY pointing at a dead proxy; TLS-inspecting corporate proxy rejecting the client cert chain; firewall blocking 443; request timeout.

Common situations: Running offline or behind a captive portal; proxy env vars set for a network the machine left; container with broken DNS; VPN split-tunnel excluding Google endpoints.

Related errors


AI-assisted analysis of googleworkspace/cli@a3768d0e82 (2026-08-16). Data as JSON: /api/errors/c9af61436882d684. Report an issue: GitHub.