You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebFlux中如何用onRetryExhaustedThrow返回原始Http状态码与消息?

WebFlux实现自定义重试并返回最后一次请求的错误详情

你的需求完全可以通过WebFlux实现,核心是在重试耗尽时,从最后一次失败的异常中提取真实的HTTP状态码、消息和响应体,而非硬编码错误信息。下面是修改后的代码及说明:

修改后的重试方法

private RetryBackoffSpec retryServerError() {
    return Retry.backoff(3, Duration.of(100, ChronoUnit.MILLIS))
                .filter(this::isServerError)
                .onRetryExhaustedThrow((retrySpec, retrySignal) -> {
                    // 获取触发重试耗尽的最后一次异常
                    Throwable lastFailure = retrySignal.failure();
                    if (lastFailure instanceof HttpServerErrorException serverErrorEx) {
                        // 复用原异常的所有错误信息:状态码、消息、响应头、响应体
                        return new HttpServerErrorException(
                            serverErrorEx.getStatusCode(),
                            serverErrorEx.getStatusText(),
                            serverErrorEx.getResponseHeaders(),
                            serverErrorEx.getResponseBodyAsByteArray(),
                            serverErrorEx.getCharset()
                        );
                    }
                    // 兜底处理,避免非预期异常导致问题
                    return new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE, "请求重试全部失败");
                });
}

private boolean isServerError(Throwable throwable) {
    return throwable instanceof HttpServerErrorException;
}

原代码的问题与优化点

  1. 硬编码错误信息:原代码中重试耗尽时固定返回SERVICE_UNAVAILABLE,丢失了最后一次请求真实的错误状态码和响应细节,修改后直接复用原异常的所有信息。
  2. 获取最后一次异常:通过retrySignal.failure()可以拿到导致重试终止的最后一次失败异常,这是提取真实错误信息的关键。
  3. 保留响应体:HttpServerErrorException本身已经包含响应体(可通过getResponseBodyAsString()或getResponseBodyAsByteArray()获取),直接传递这些信息到新抛出的异常中,上层就能拿到完整的错误详情。

保留原请求方法

你的post方法无需大幅修改,保持原逻辑即可:

public ResponseEntity<U> post(Class<Void> responseClass, Function<UriBuilder, URI> uri, MyBodyObject body) throws WebClientException, RestClientResponseException {
    return this.getWebClientBuilder()
               .build()
               .post()
               .uri(uri)
               .body(BodyInserters.fromValue(body))
               .retrieve()
               .toEntity(responseClass)
               .retryWhen(retryServerError())
               .block();
}

注意:WebClient的retrieve()方法默认会在收到5xx响应时抛出HttpServerErrorException,该异常包含完整的HTTP响应信息,这也是我们能提取到真实错误细节的基础。

内容的提问来源于stack exchange,提问作者Jérémy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:03:21