{"record":{"id":"e805ab4906dad777","repo":"zed-industries/zed","slug":"failed-to-connect-to-sentry-api-error-reason","errorCode":null,"errorMessage":"Failed to connect to Sentry API: {error.reason}","messagePattern":"Failed to connect to Sentry API: (.+?)","errorType":"exception","errorClass":"FetchError","httpStatus":null,"severity":"error","filePath":"script/select-sentry-crash-candidates","lineNumber":63,"sourceCode":"\ndef api_get(path: str, token: str):\n    url = f\"{SENTRY_BASE_URL}{path}\"\n    request = urllib.request.Request(url)\n    request.add_header(\"Authorization\", f\"Bearer {token}\")\n    request.add_header(\"Accept\", \"application/json\")\n\n    try:\n        with urllib.request.urlopen(request, timeout=30) as response:\n            return json.loads(response.read().decode(\"utf-8\"))\n    except urllib.error.HTTPError as error:\n        body = error.read().decode(\"utf-8\", errors=\"replace\")\n        try:\n            detail = json.loads(body).get(\"detail\", body)\n        except (json.JSONDecodeError, AttributeError):\n            detail = body\n        raise FetchError(f\"Sentry API returned HTTP {error.code} for {path}: {detail}\")\n    except urllib.error.URLError as error:\n        raise FetchError(f\"Failed to connect to Sentry API: {error.reason}\")\n\n\ndef fetch_issues(token: str, organization: str, limit: int, query: str):\n    encoded_query = urllib.parse.quote(query)\n    path = (\n        f\"/organizations/{organization}/issues/\"\n        f\"?limit={limit}&sort=freq&query={encoded_query}\"\n    )\n    return api_get(path, token)\n\n\ndef fetch_latest_event(token: str, issue_id: str):\n    return api_get(f\"/issues/{issue_id}/events/latest/\", token)\n\n\ndef parse_int(value, fallback=0) -> int:\n    try:\n        return int(value)","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/script/select-sentry-crash-candidates#L45-L81","documentation":"Raised by api_get() in script/select-sentry-crash-candidates when urllib raises URLError (anything other than an HTTP-level error): the request to the Sentry host never completed. Reasons include DNS resolution failure, connection refused, TLS handshake errors, proxy failures, and timeouts (a 30s socket timeout surfaces here as URLError wrapping the timeout).","triggerScenarios":"Running the script where egress to sentry.io is blocked (CI sandbox, offline machine, VPN split-tunnel); HTTPS_PROXY required but unset; DNS failing for the Sentry host; the API base URL overridden to an unreachable internal host; Sentry outage.","commonSituations":"CI job without corporate proxy env vars; laptop on a network with a TLS-intercepting proxy whose CA is not trusted; /etc/resolv.conf broken in a container; status.sentry.io reporting an incident.","solutions":["From the same environment run: curl -sS -o /dev/null -w '%{http_code}' https://sentry.io/api/0/ to confirm egress","Set HTTPS_PROXY/HTTP_PROXY (and NO_PROXY where needed) if a corporate proxy is required","Check DNS (getent hosts sentry.io) and TLS trust (proxy MITM CA installed into the trust store)","Check status.sentry.io for an outage before debugging locally"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Cheap connectivity pre-flight before the run\nimport socket, ssl\n\ndef can_reach_sentry(host: str = \"sentry.io\") -> bool:\n    try:\n        with socket.create_connection((host, 443), timeout=5):\n            return True\n    except OSError:\n        return False","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        return api_get(path, token)\n    except FetchError as error:\n        if \"Failed to connect\" not in str(error):\n            raise\n        time.sleep(2 ** attempt)  # transient DNS/proxy/TLS failures often clear","preventionTips":["Run a TCP/TLS reachability check to sentry.io before batch jobs","Set HTTPS_PROXY/HTTP_PROXY in CI environments that require an egress proxy","Keep the existing timeout=30 so connection failures surface instead of hanging"],"tags":["python","sentry","network","dns","proxy","timeout"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}