Skip to content

fix(gmail-oauth-draft): wrap api_get with HTTPError handler for clean failure surface#240

Merged
potiuk merged 1 commit into
apache:mainfrom
andreahlert:fix/gmail-api-get-httperror
May 20, 2026
Merged

fix(gmail-oauth-draft): wrap api_get with HTTPError handler for clean failure surface#240
potiuk merged 1 commit into
apache:mainfrom
andreahlert:fix/gmail-api-get-httperror

Conversation

@andreahlert
Copy link
Copy Markdown
Collaborator

What

api_get was the only urllib.request.urlopen call in the oauth-draft package without a try/except urllib.error.HTTPError. api_post, both calls in mark_threads_read, and the token refresh in credentials.py all wrap the call and raise SystemExit with a one-line "Gmail API <path> failed (<code>): <body>" message.

Impact

api_get is the path that latest_reply_headers uses, so any 401 / 403 / 404 from GET /threads/{id}?format=full (token expired, thread missing, missing scope) surfaced as a raw Python traceback instead of the clean error the rest of the tool produces. That path is exercised on every oauth-draft-create --thread-id <X> invocation that does not pass --no-reply-headers.

Fix

Wraps api_get with the same handler as api_post and adds a regression test mirroring test_api_post_raises_on_http_error.

Changes

  • src/oauth_draft/create_draft.pyapi_get wrapped with try/except urllib.error.HTTPError
  • tests/test_create_draft.py — regression test asserting api_get raises SystemExit with the failed (<code>) shape on a Gmail 404

Validation

  • pytest: 59 passed
  • ruff check / ruff format / mypy: clean
  • prek: all hooks pass

… failure surface

`api_get` was the only `urllib.request.urlopen` call in the package
without a `try/except urllib.error.HTTPError`. `api_post`,
`mark_threads_read` (both calls), and the token refresh in
`credentials.py` all wrap the call and raise `SystemExit` with a
one-line `"Gmail API <path> failed (<code>): <body>"` message.

`api_get` is the path that `latest_reply_headers` uses, so any
401 / 403 / 404 from `GET /threads/{id}?format=full` surfaced as a
raw Python traceback instead of the clean error the rest of the
tool produces. That path is exercised on every
`oauth-draft-create --thread-id <X>` invocation that does not pass
`--no-reply-headers`.

Wraps `api_get` with the same handler as `api_post` and adds a
regression test mirroring `test_api_post_raises_on_http_error`.
@andreahlert andreahlert requested a review from potiuk May 20, 2026 07:47
@andreahlert andreahlert self-assigned this May 20, 2026
@potiuk potiuk merged commit 76dcb97 into apache:main May 20, 2026
13 checks passed
@andreahlert andreahlert deleted the fix/gmail-api-get-httperror branch May 20, 2026 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants