Skip to content

fix: raise on 401/403 instead of retrying, and fix README's undocumented async-with usage - #40

Merged
Bre77 merged 1 commit into
mainfrom
fm/lib-stream-readme-and-auth-error
Aug 26, 2026
Merged

fix: raise on 401/403 instead of retrying, and fix README's undocumented async-with usage#40
Bre77 merged 1 commit into
mainfrom
fm/lib-stream-readme-and-auth-error

Conversation

@Bre77

@Bre77 Bre77 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Intent

  • The README's examples used async with TeslemetryStream(...) as stream:, but the class has never implemented __aenter__/__aexit__ - following the README raises TypeError: ... does not support the asynchronous context manager protocol on the very first line.
    • Fixed the docs rather than adding a context manager: the connection lifecycle here is deliberately listener-driven (AGENTS.md already documents the async_add_listener/auto-close machinery in detail, with dedicated lifecycle tests), and a context manager whose __aenter__ does nothing but return self would just be a second, redundant way to spell the same thing while implying a connect step that isn't actually needed. Rewrote the two affected examples to plain instantiation + async_add_listener, and reworded the Usage section to describe the listener-driven default plus the manual connect()/close()/listen() alternative that was already correctly documented elsewhere in the README.
  • aiohttp.ClientResponseError (raised by connect()'s raise_for_status=True) is a subtype of aiohttp.ClientError, so a 401/403 from a bad or revoked access token was falling into __anext__'s generic client-error handler and being retried forever with backoff - the caller saw no events and no error, indistinguishable from a quiet vehicle.
    • __anext__ now special-cases a 401/403 ClientResponseError: it stops the stream and raises a new TeslemetryStreamAuthenticationError (chaining the original error), instead of retrying. Every other ClientError, including other response statuses, keeps the existing backoff-and-reconnect behavior unchanged - verified by tests/test_auth_failure.py, which covers both the 401/403 case and a genuine transient ClientError still retrying and reconnecting.

Ran uv run --with ruff ruff check . and uv run --with mypy mypy teslemetry_stream (both clean save for pre-existing lint findings in the example scripts, unrelated to this change), and every tests/test_*.py script directly.

…ted async-with usage

TeslemetryStream never implemented __aenter__/__aexit__ - the connection
lifecycle is deliberately listener-driven (async_add_listener connects on
the first listener, disconnects on the last removed), with connect()/
close()/listen() as the manual alternative. The README's async-with
examples didn't match either path and raised TypeError on first use, so
they're rewritten to the listener-driven pattern the class actually
supports.

Separately, aiohttp.ClientResponseError is a subtype of ClientError, so a
401/403 from a bad access token was being retried forever as if it were a
transient network blip - the caller saw no events and no error. __anext__
now treats 401/403 as terminal and raises TeslemetryStreamAuthenticationError
instead of retrying; every other ClientError (including other response
statuses) keeps the existing backoff-and-reconnect behavior unchanged.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Bre77 Bre77 added the fm Opened by a Firstmate crewmate label Aug 25, 2026
@Bre77
Bre77 merged commit e2cabdf into main Aug 26, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fm Opened by a Firstmate crewmate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant