Expose body for non RFC 9457 error responses#1955
Conversation
Log only on DEBUG level This closes #1844
faba5ac to
7090d43
Compare
gnodet
left a comment
There was a problem hiding this comment.
Review Summary
Thanks for working on this, @kwin! Making non-RFC 9457 error response bodies visible for debugging is a useful improvement. I found one confirmed bug and a few design concerns worth discussing.
Bug: UncheckedIOException crashes the error-handling path
File: RFC9457Reporter.java (line ~105 in the else branch)
The catch (IOException e) block throws new UncheckedIOException(...). If getBody(response) encounters any I/O error (entirely plausible on network streams), this UncheckedIOException propagates up and prevents baseException.accept(statusCode, reasonPhrase) from ever executing. A failure in a diagnostic/debug code path should never abort the main error-handling flow. The IOException should be caught and logged or swallowed:
} catch (IOException e) {
LOGGER.debug("Failed to read response body for status code {}", statusCode, e);
}Concern: Eager stream consumption even when DEBUG is disabled
getBody(response) is passed as a direct argument to LOGGER.debug(), which means the response body stream is always consumed — even when DEBUG logging is disabled. For JDK and Jetty transports, this reads the entire InputStream on every non-RFC-9457 error response, wasting I/O unnecessarily. Consider guarding with LOGGER.isDebugEnabled() or using a lazy supplier.
Concern: Unbounded body size
The response body is read fully into a String with no size limit. A multi-megabyte HTML error page would be fully materialized in memory and logged. Consider truncating to a reasonable limit (e.g., 4096 characters).
Concern: slf4j-api added to SPI module
Adding slf4j-api as a compile-scope dependency to the SPI module increases the transitive dependency footprint for all SPI consumers. The SPI module currently has minimal dependencies (maven-resolver-api and gson). Consider whether this logging belongs in the transport implementations instead.
Note: DEBUG-only vs. issue #1844 intent
Issue #1844 asks for the body to be "exposed (at least partially) in the exception." The current implementation only logs at DEBUG level, which may not be sufficient for regular users diagnosing errors without debug logging enabled. This may be a deliberate design choice, but worth confirming it satisfies the issue's requirements.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
|
Few remarks here:
I'd rather not introduce logging here, but some sort of |
| throw new HttpRFC9457Exception(statusCode, reasonPhrase, rfc9457Payload); | ||
| } | ||
| throw new HttpRFC9457Exception(statusCode, reasonPhrase, RFC9457Payload.INSTANCE); | ||
| } else { |
There was a problem hiding this comment.
Per the Javadoc comment above this is incorrect. baseException should be thrown. I'm not sure if this should be fixed or if the doc needs to be changed, but they should be consistent
| statusCode, | ||
| getBody(response)); | ||
| } catch (IOException e) { | ||
| throw new UncheckedIOException("Failed to read response body", e); |
There was a problem hiding this comment.
probably not worth throwing this at all if it just means we couldn't log a debug message
|
Thanks for the reviews.
Any pointers how to not make it too verbose? Collecting all failed response bodies (even extracts) may be too heavyweight or do you suggest only collecting the first/last one? Who should be responsible for logging?
|
|
I would go with simplest solution:
@gnodet maybe some ideas? |
|
I agree with @cstamas that the SPI module should not pull in a logger dependency, and that a Here's a possible direction:
For the session config key, something like This way the SPI stays dependency-free, the body is available where it matters (build failure output), and the transport implementations just need to call the consumer when they have a response body to report. |
gnodet
left a comment
There was a problem hiding this comment.
The review feedback from maintainers (gnodet, cstamas, elharo — July 13) has not been addressed. The PR still contains only the original commit from July 11.
Key unresolved issues:
-
Bug — UncheckedIOException crashes error-handling path: The
catch (IOException e)block on line 107 throwsUncheckedIOException, which propagates out and preventsbaseException.accept(statusCode, reasonPhrase)from executing. A failure in a diagnostic/debug code path must never abort the main error-handling flow. -
Architecture — slf4j-api in SPI module: Adding slf4j-api as a compile dependency to the SPI module has been explicitly rejected by maintainers. cstamas stated "I dislike SPI pulling in logger, that is wrong IMHO" and gnodet agreed. The maintainers converged on a Consumer-based callback approach instead.
-
Eager stream consumption:
getBody(response)is evaluated as a method argument toLOGGER.debug()regardless of whether DEBUG is enabled — the full response body is always read. -
No body size limit: The response body is read fully into a String with no truncation. A multi-megabyte HTML error page would be fully materialized in memory.
-
Doesn't satisfy issue #1844: The issue asks to "expose (at least partially) [the response body] in the exception." DEBUG-only logging doesn't meet this requirement for production builds.
-
No test coverage for the new else branch in
generateException().
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
Log only on DEBUG level
This closes #1844
Following this checklist to help us incorporate your
contribution quickly and easily:
Note that commits might be squashed by a maintainer on merge.
This may not always be possible but is a best-practice.
mvn verifyto make sure basic checks pass.A more thorough check will be performed on your pull request automatically.
mvn -Prun-its verify).If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.
To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.