{"record":{"id":"c28c2b980f6b1939","repo":"googleworkspace/cli","slug":"5-c28c2b","errorCode":"5","errorMessage":"HTTP request failed: {e}","messagePattern":"HTTP request failed: (.+?)","errorType":"exception","errorClass":"GwsError","httpStatus":null,"severity":"error","filePath":"crates/google-workspace-cli/src/helpers/workflows.rs","lineNumber":244,"sourceCode":"}\n\n// ---------------------------------------------------------------------------\n// Handlers\n// ---------------------------------------------------------------------------\n\nasync fn get_json(\n    client: &reqwest::Client,\n    url: &str,\n    token: &str,\n    query: &[(&str, &str)],\n) -> Result<Value, GwsError> {\n    let resp = client\n        .get(url)\n        .query(query)\n        .bearer_auth(token)\n        .send()\n        .await\n        .map_err(|e| GwsError::Other(anyhow::anyhow!(\"HTTP request failed: {e}\")))?;\n\n    if !resp.status().is_success() {\n        let status = resp.status();\n        let body = resp.text().await.unwrap_or_default();\n        return Err(GwsError::Api {\n            code: status.as_u16(),\n            message: body,\n            reason: \"workflow_request_failed\".to_string(),\n            enable_url: None,\n        });\n    }\n\n    resp.json::<Value>()\n        .await\n        .map_err(|e| GwsError::Other(anyhow::anyhow!(\"JSON parse failed: {e}\")))\n}\n\nfn format_and_print(value: &Value, matches: &ArgMatches) {","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/googleworkspace/cli/blob/a3768d0e82ad83cca2da97724e46bea4ff0e6dbd/crates/google-workspace-cli/src/helpers/workflows.rs#L226-L262","documentation":"Transport-level failure inside `get_json()`, the shared GET helper used by every workflow helper (`+standup-report`, `+focus`, etc.). The reqwest `send()` itself errored — DNS failure, connection refused/reset, TLS problem, or an invalid proxy — before any HTTP status existed. Distinct from the sibling branch which turns non-2xx statuses into `GwsError::Api` with reason `workflow_request_failed`.","triggerScenarios":"Running `gws calendar +standup-report` (or any workflow helper) with no internet; DNS for `www.googleapis.com`/`tasks.googleapis.com` failing; HTTPS_PROXY pointing at a dead proxy; a firewall silently resetting connections to Google endpoints.","commonSituations":"CI runners with restricted egress; laptops in airplane mode; corporate networks requiring a proxy that is not exported into the shell running gws.","solutions":["Verify egress: `curl -sS -o /dev/null -w '%{http_code}' https://www.googleapis.com/` should print an HTTP code.","Fix or unset broken proxy env vars (HTTPS_PROXY, ALL_PROXY) in the shell/session running gws.","Retry — this path has no automatic retry, and transient resets are common on flaky links.","On locked-down CI, allowlist *.googleapis.com (and accounts.google.com) in the egress firewall."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// wrap workflow helper invocations with bounded retry on transport errors\nfor attempt in 1..=3 {\n    match run_workflow(&args).await {\n        Err(GwsError::Other(e)) if e.to_string().contains(\"HTTP request failed\") && attempt < 3 => {\n            tokio::time::sleep(std::time::Duration::from_secs(2u64.pow(attempt))).await;\n        }\n        other => return other,\n    }\n}","preventionTips":["Ensure egress to *.googleapis.com works before scheduling workflow helpers (`curl -sI https://www.googleapis.com`).","Export proxy variables consistently in cron/systemd units that invoke gws.","Prefer Discovery commands with built-in send_with_retry for critical paths; workflow helpers lack automatic retry today."],"tags":["network","workflows","reqwest","transport-error","google-api"],"backgroundTag":"http-connection-error","analyzedSha":"a3768d0e82ad83cca2da97724e46bea4ff0e6dbd","analyzedAt":"2026-08-16T19:51:46.516Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}