Skip to content

fix: preserve exception type when a transport error has a blank message - #76

Merged
acrogenesis merged 1 commit into
mainfrom
fix/transport-exception-blank-message
Jun 24, 2026
Merged

fix: preserve exception type when a transport error has a blank message#76
acrogenesis merged 1 commit into
mainfrom
fix/transport-exception-blank-message

Conversation

@acrogenesis

Copy link
Copy Markdown
Member

Problem

When a request raised a transport exception, the high-level helpers caught it with:

errors = [{"message": str(e)}]

But httpx timeout and connection-reset exceptions carry an empty message — str(httpx.ReadTimeout("")) is "". So a timed-out (or reset) request surfaced as:

[{"message": ""}]

A blank, undiagnosable error: the exception type is lost, so callers can't tell a timeout from any other failure. This is most visible on async_mutate, where async httpx timeouts always stringify to "" (the sync path happens to carry "timed out").

Fix

Add an exception_errors helper that falls back to repr(error) when the message is blank, preserving the exception class name (e.g. ReadTimeout('')). A non-empty message is still reported verbatim. Wired into query, mutate, async_query, and async_mutate.

def exception_errors(error: Exception) -> list[dict]:
    return [{"message": str(error) or repr(error)}]

Tests

New integration test (tests/pygqlc/gql_client/test_timeout_empty_message.py) drives a real GraphQLClient against a local HTTP server stalled past post_timeout (no mocks), asserting that both sync and async paths surface a non-blank, timeout-identifying error. Plus unit coverage that a blank-message exception keeps its type and a real message is preserved verbatim. All 4 pass; each fails against the pre-fix code.

No new lint findings introduced (pre-existing ruff findings in GraphQLClient.py left untouched).

🤖 Generated with Claude Code

httpx timeout and connection-reset exceptions stringify to "" (e.g.
`str(httpx.ReadTimeout(""))` is ""). The high-level helpers caught these
with `errors = [{"message": str(e)}]`, so a timed-out request surfaced as
`[{"message": ""}]` — a blank, undiagnosable error. This was most visible
on `async_mutate`, where async httpx timeouts always carry an empty message.

Add an `exception_errors` helper that falls back to `repr(error)` when the
message is blank, keeping the exception class name (e.g. `ReadTimeout('')`),
and use it in `query`, `mutate`, `async_query`, and `async_mutate`. A real
message is still reported verbatim.

Includes an integration test driving a real GraphQLClient against a local
HTTP server stalled past `post_timeout`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uhj6eA8d9jcAzzHuzqtPod

@palantir-valiot palantir-valiot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall Assessment

This PR introduces an exception_errors helper that falls back to repr(error) when str(error) is blank, preventing transport exceptions (e.g., httpx.ReadTimeout('')) from surfacing as [{"message": ""}]. The change is applied consistently to query, mutate, async_query, and async_mutate. Version bump, changelog entry, and new tests (real-server integration + unit) all follow repo conventions. No blocking bugs found.

Findings

No actionable findings.

Notes

  • The docstring on exception_errors (lines 100-108 of GraphQLClient.py) explicitly documents the design rationale, so the str or repr fallback is intentional rather than an oversight.
  • Test coverage is strong: four new tests (two unit, two integration) each fail against the pre-fix code; the integration tests drive a real GraphQLClient against a stalled local HTTP server with no mocks, aligning with AGENTS.md guidance.
  • No remaining instances of the old [{"message": str(e)}] pattern exist in the codebase after this change.

@acrogenesis
acrogenesis merged commit b8a1958 into main Jun 24, 2026
7 checks passed
@acrogenesis
acrogenesis deleted the fix/transport-exception-blank-message branch June 24, 2026 18:45
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.

1 participant