Skip to content

fix: JSONRPCTransport swallows HTTP status code in error responses #799

@pratik3558

Description

@pratik3558

Summary

When JSONRPCTransport receives a non-2xx HTTP response (e.g. 401, 403, 429, 503), it throws a plain IOException with the status code embedded as a string:

throw new IOException("Request failed " + response.status());

This gets wrapped into a generic A2AClientException, making it impossible for callers to programmatically distinguish 4xx from 5xx errors without fragile string parsing.

Expected Behavior

Callers should be able to inspect the HTTP status code in a structured way, e.g.:

} catch (A2AClientException e) {
    if (e.getCause() instanceof A2AClientHTTPError httpErr) {
        int status = httpErr.getCode(); // e.g. 401, 503
    }
}

Current Behavior

The status code is only available by parsing the exception message string, e.g. "Request failed 503".

Additional Context

  • A2AClientHTTPError already exists in the spec module and was designed for exactly this purpose, but is unused by JSONRPCTransport.
  • The fix should be fully backward compatible — all callers already declare throws A2AClientException, so no signatures change.
  • The existing code, message, and getCode() fields on A2AClientHTTPError must be preserved.
  • A2AClientHTTPError also currently silently drops the data constructor parameter — the response body should be stored and exposed via getResponseBody() so callers can inspect gateway error payloads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions