Fix the WebClient plugins' NPE when writeTo runs before the exit spanis created - #834
Conversation
|
The deferred injection in .filter((req, next) -> next.exchange(req)
.flatMap(r -> r.statusCode().is5xxServerError()
? r.releaseBody().then(Mono.<ClientResponse>error(new IllegalStateException("5xx")))
: Mono.just(r))
.retry(1))With I reproduced it against Spring 6.2.19 with the JDK connector, a server that returns 503 and then 200, and the deferred injection emulated as in this PR:
Before this PR the NPE was caught and only logged, so as written this turns a logging problem into a request failure. Could you guard the deferred injection in both the 5.x and 6.x interceptors? For example: if (contextCarrier != null) {
try {
inject(clientHttpRequest, contextCarrier);
} catch (Throwable t) {
// headers are read-only once the request is committed (e.g. re-subscribed by a retry)
}
} |
When the exchange Mono is re-subscribed, e.g. by a retry in an ExchangeFilterFunction, the deferred injection re-runs against the same already committed ClientHttpRequest whose headers are read-only, and the UnsupportedOperationException propagates into the application's reactive chain and fails the request. Catch it in both the 5.x and 6.x interceptors, as suggested in the review of apache#834: the sw8 header injected on the first subscription is still sent on the retried request.
|
@wu-sheng Thanks! Fixed with the suggested try/catch in both interceptors. |
Fix
CHANGESlog.