Skip to content

fix(exceptions): classify 502 responses as TeslaFleetError - #148

Merged
Bre77 merged 2 commits into
mainfrom
fm/tfa-gateway-unreachable-error
Sep 5, 2026
Merged

fix(exceptions): classify 502 responses as TeslaFleetError#148
Bre77 merged 2 commits into
mainfrom
fm/tfa-gateway-unreachable-error

Conversation

@Bre77

@Bre77 Bre77 commented Sep 5, 2026

Copy link
Copy Markdown
Member

Intent

Move Powerwall gateway-unreachable classification out of Home Assistant into this library (HA core PR home-assistant/core#181320). Fix: any 502 response from the Fleet/Teslemetry API - bodied or bodyless - now raises tesla_fleet_api.exceptions.BadGateway(TeslaFleetError) instead of a JSON-bodied 502 leaking as a raw aiohttp.ClientResponseError (raise_for_status previously had no 502 branch at all). CAPTAIN REVIEW DECISION applied on this branch: an earlier version of this change also added a specialized EnergyGatewayUnreachable exception and per-endpoint (gateway-relay) 502 mapping scoped to the Powerwall local-control pairing/authorized-clients endpoints (add_authorized_client, authorized_clients, remove_authorized_client, networking_status). The captain reviewed PR #148 and decided a Powerwall gateway-relay 502 is not semantically distinct from any other 502, so that specialization was deliberately removed: EnergyGatewayUnreachable and the endpoint-matching regex are gone, and ALL 502s (from any endpoint) now raise the single generic BadGateway. Tests in tests/test_bad_gateway_classification.py were updated to match: a JSON-bodied 502 -> BadGateway (not ClientResponseError), a bodyless 502 -> BadGateway, and a 502 from a non-gateway endpoint -> BadGateway (same class, not a different one) - there is no longer any endpoint-specific branching to test. docs/energy_local_control.md was trimmed to one line stating any 502 raises BadGateway. No other status code mapping changed and there are no consumer-facing signature changes. This is a pragmatic-version PR: no version bump, since a separate release process cuts that.

What Changed

  • Added BadGateway(TeslaFleetError) (status 502) to tesla_fleet_api/exceptions.py and wired a 502 branch into raise_for_status(), so any 502 response — bodied or bodyless, from any endpoint — raises BadGateway instead of leaking an unhandled aiohttp.ClientResponseError.
  • Added tests/test_bad_gateway_classification.py covering a JSON-bodied 502, a bodyless 502, and a 502 from a non-gateway endpoint, all asserting the same BadGateway class with no endpoint-specific branching.
  • Updated docs/energy_local_control.md with a one-line note that any 502, including from a gateway-relay command endpoint, raises BadGateway regardless of body presence.

Risk Assessment

✅ Low: Small, well-bounded change: adds a single BadGateway exception and one raise_for_status branch, cleanly reverts the previously-added endpoint-specific EnergyGatewayUnreachable/regex with no leftover references, matches the stated intent exactly, and is covered by behavioral tests that exercise the real request path.

Testing

Ran the targeted regression suite tests/test_bad_gateway_classification.py (3/3 passed) covering JSON-bodied, bodyless, and non-gateway-endpoint 502 responses, all correctly raising the single generic BadGateway(TeslaFleetError); confirmed against the base commit that no 502 branch previously existed (500→503 directly), so a 502 would have leaked as a raw aiohttp.ClientResponseError, validating this is a genuine fix with real regression coverage. Also confirmed no residual EnergyGatewayUnreachable or endpoint-matching code remains anywhere in the repo, matching the captain's decision to keep the fix generic, and that docs/energy_local_control.md was trimmed as described. No code changes were needed; working tree is clean.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • uv run pytest tests/test_bad_gateway_classification.py -v (3 passed: test_json_bodied_502_raises_bad_gateway, test_bodyless_502_raises_bad_gateway, test_non_gateway_endpoint_502_also_raises_bad_gateway)
  • git diff de474c00..c43cffd -- tesla_fleet_api/exceptions.py docs/energy_local_control.md (confirmed single generic BadGateway added, no per-endpoint branching)
  • grep -rn EnergyGatewayUnreachable . (confirmed zero remaining references, matching captain's removal decision)
  • git show de474c00:tesla_fleet_api/exceptions.py | grep 50[0-9] (confirmed base commit had no 502 branch, i.e. a 502 would have leaked as raw aiohttp.ClientResponseError before this fix)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

…reachable

A JSON-bodied 502 fell through raise_for_status's status table and hit the
trailing resp.raise_for_status(), leaking a raw aiohttp.ClientResponseError
instead of a TeslaFleetError; a bodyless 502 already raised ResponseError.
Add an explicit 502 branch (BadGateway) so both shapes raise a typed error,
and specialize it to EnergyGatewayUnreachable for the gateway-relay
endpoints the Powerwall local-control pairing/authorized-clients flow uses,
so consumers (see home-assistant/core#181320) no longer need to duplicate
this classification themselves.

Claude-Session: https://claude.ai/code/session_01Aukcht9BRfsyGsnM1x6mnr
@Bre77 Bre77 added the fm Opened by a Firstmate crewmate label Sep 5, 2026
…ay for all 502s

Captain review: a Powerwall gateway-relay 502 is not semantically distinct
from any other 502, so a dedicated exception and per-endpoint mapping added
unwarranted surface. Keep only the classification fix - any 502, bodied or
bodyless, now raises BadGateway(TeslaFleetError) instead of leaking a raw
aiohttp.ClientResponseError for the JSON-bodied case.

Claude-Session: https://claude.ai/code/session_01Aukcht9BRfsyGsnM1x6mnr
@Bre77
Bre77 merged commit 2ecc0dc into main Sep 5, 2026
6 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