Skip to content

SDK drift: Python's FeedClient._request crashes with unwrapped JSONDecodeError on a malformed JSON error body; TypeScript falls back gracefully #1700

Description

@realfishsam

Drift

On a non-2xx response, TypeScript attempts response.json() with a .catch(() => ({})) fallback, so a non-JSON error body (e.g. an HTML error page from a proxy/load balancer) still results in a typed PmxtError. Python's equivalent error-body parsing has no such fallback — json.loads(e.read()) is not wrapped in a try/except, so a non-JSON error body raises a raw, unwrapped json.JSONDecodeError instead of PmxtError.

TypeScript SDK

sdks/typescript/pmxt/feed-client.ts:145-148:

if (!response.ok) {
    const body = await response.json().catch(() => ({}));
    throw new PmxtError(body.error || response.statusText);
}

Python SDK

sdks/python/pmxt/feed_client.py:188-195:

try:
    with urllib.request.urlopen(req, timeout=30) as resp:
        body = json.loads(resp.read())
except urllib.error.HTTPError as e:
    body = json.loads(e.read()) if e.fp else {}
    msg = body.get("error", e.reason)
    raise PmxtError(f"Feed API error ({e.code}): {msg}") from e

Expected

Python's _request should catch JSON-decode failures on the error-body path the same way TypeScript does, falling back to an empty body/using e.reason and still raising a typed PmxtError.

Impact

Any non-2xx response with a non-JSON body (e.g. from an intermediary proxy, load balancer, or CDN error page) crashes the Python SDK with an unwrapped json.JSONDecodeError instead of the expected typed PmxtError, breaking any caller's except PmxtError handling. This is a distinct bug from existing issue #1476, which is scoped only to the message format of the resulting PmxtError, not to a crash that produces no PmxtError at all.


Found by automated SDK cross-language drift audit

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions