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.
Summary
When
JSONRPCTransportreceives a non-2xx HTTP response (e.g. 401, 403, 429, 503), it throws a plainIOExceptionwith the status code embedded as a string: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.:
Current Behavior
The status code is only available by parsing the exception message string, e.g.
"Request failed 503".Additional Context
A2AClientHTTPErroralready exists in thespecmodule and was designed for exactly this purpose, but is unused byJSONRPCTransport.throws A2AClientException, so no signatures change.code,message, andgetCode()fields onA2AClientHTTPErrormust be preserved.A2AClientHTTPErroralso currently silently drops thedataconstructor parameter — the response body should be stored and exposed viagetResponseBody()so callers can inspect gateway error payloads.