{"record":{"id":"c19f527bb1f17792","repo":"666ghj/MiroFish","slug":"github-api-request-could-not-be-started","errorCode":null,"errorMessage":"GitHub API request could not be started","messagePattern":"GitHub API request could not be started","errorType":"exception","errorClass":"FetchError","httpStatus":null,"severity":"error","filePath":"scripts/fetch_star_count.py","lineNumber":96,"sourceCode":"        headers={\n            \"Accept\": \"application/vnd.github+json\",\n            \"Authorization\": f\"Bearer {token}\",\n            \"User-Agent\": \"Repository-Star-History-Fetcher\",\n            \"X-GitHub-Api-Version\": API_VERSION,\n        },\n        method=\"GET\",\n    )\n    client = opener or _build_opener()\n    try:\n        response = client.open(request, timeout=TIMEOUT_SECONDS)\n    except urllib.error.HTTPError as exc:\n        status = exc.code\n        exc.close()\n        raise _status_error(status) from None\n    except (urllib.error.URLError, TimeoutError, OSError):\n        raise FetchError(\"GitHub API network request failed\") from None\n    except Exception:\n        raise FetchError(\"GitHub API request could not be started\") from None\n\n    try:\n        with response:\n            if response.geturl() != API_URL:\n                raise FetchError(\"GitHub API redirect was refused\")\n            status = response.getcode()\n            if status != 200:\n                raise _status_error(status)\n            payload = _read_response(response)\n    except FetchError:\n        raise\n    except (TimeoutError, OSError):\n        raise FetchError(\"GitHub API response could not be read\") from None\n    except Exception:\n        raise FetchError(\"GitHub API response could not be processed\") from None\n\n    try:\n        document = json.loads(payload)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/fetch_star_count.py#L78-L114","documentation":"The catch-all for any exception from client.open that is not HTTPError, URLError, TimeoutError, or OSError — for example ValueError from a malformed request object, TypeError from a bad opener, or an unexpected exception type leaking from a custom opener passed via the opener parameter. It marks failures to even start the request, as opposed to network failures mid-flight.","triggerScenarios":"Calling fetch_star_count(token, opener=my_opener) with an opener whose .open raises an arbitrary exception (not OSError-derived); a Request object invalidated by exotic header handling; programming errors in custom openers used for testing.","commonSituations":"Test doubles that raise pytest.fail or custom exceptions instead of OSError; monkeypatched urlopen raising RuntimeError; a custom opener that does not implement the OpenerDirector protocol.","solutions":["If passing a custom opener, make its failure modes raise urllib.error.URLError or OSError so they map to the more precise 'network request failed' error.","Inspect the chained exception (raise ... from None discards it in this branch — reproduce without the wrapper to see the original traceback).","In tests, assert against this message when deliberately raising unexpected exceptions, or fix the double to raise standard library errors."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import urllib.request\n\ndef is_usable_opener(opener: object) -> bool:\n    \"\"\"An opener must expose OpenerDirector.open before we rely on it.\"\"\"\n    return callable(getattr(opener, \"open\", None))","typeGuard":null,"tryCatchPattern":"try:\n    count = fetch_star_count(token, opener=my_opener)\nexcept FetchError as exc:\n    if exc.args[0] == \"GitHub API request could not be started\":\n        # the custom opener raised an unexpected exception type;\n        # run the opener directly once to capture the real traceback\n        raise","preventionTips":["Custom openers should raise urllib.error.URLError or OSError so failures map to the precise network error.","Test doubles must implement .open(request, timeout) returning a context-managed HTTPResponse-like object.","Treat this catch-all as a bug indicator in your opener, not a GitHub-side problem."],"tags":["fetch-star-count","opener","testing","unexpected-exception"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}