使用block()时如何将WebClient特定异常转换为自定义异常?
解决OpenApi生成WebClient的BadRequest异常转换问题
问题根源分析
OpenApi生成的WebClient通常会将底层的WebClientResponseException包装为自己定义的ApiException,直接捕获WebClientResponseException.BadRequest会因为异常类型不匹配而失效。另外,若异常匹配逻辑仅依赖子类判断,也可能遗漏通过状态码标识的BadRequest场景。
解决方案
1. 针对OpenApi封装的ApiException处理
直接捕获ApiException,从中提取原始异常后判断状态码:
yourOpenApiClient.targetApiMethod() .onErrorResume(ApiException.class, apiEx -> { Throwable rootCause = apiEx.getCause(); if (rootCause instanceof WebClientResponseException webEx && webEx.getStatusCode() == HttpStatus.BAD_REQUEST) { return Flux.error(new CustomException("请求参数非法", webEx)); } // 非目标异常直接抛出 return Flux.error(apiEx); });
2. 全局统一异常处理(Spring MVC环境)
通过WebClientCustomizer给OpenApi生成的WebClient添加全局过滤器,避免重复编写异常处理逻辑:
@Configuration public class OpenApiWebClientConfig { @Bean public WebClientCustomizer badRequestExceptionHandler() { return builder -> builder .filter((request, next) -> next.exchange(request) .onErrorResume(ex -> { if (ex instanceof WebClientResponseException webEx && webEx.getStatusCode() == HttpStatus.BAD_REQUEST) { return Mono.error(new CustomException("参数错误", webEx)); } return Mono.error(ex); })); } }
注意:需确保该Customizer被应用到OpenApi生成的WebClient实例上。
3. 精准匹配原始WebClient异常
若未被ApiException包装,直接通过状态码判断而非依赖子类:
yourWebClient.get() .uri("/target-api") .retrieve() .bodyToFlux(YourResponse.class) .onErrorResume(WebClientResponseException.class, webEx -> { if (webEx.getStatusCode() == HttpStatus.BAD_REQUEST) { return Flux.error(new CustomException("请求参数错误", webEx)); } return Flux.error(webEx); });
注意事项
- 确认OpenApi生成配置中
throwExceptionOnError为开启状态(默认开启),否则非2xx响应不会转为异常。 - 避免在
onErrorResume中返回空Flux或默认值,除非业务明确允许,否则应抛出自定义异常交由上层统一处理。
内容的提问来源于stack exchange,提问作者Daniel_Ovelheiro
相关产品推荐
相关产品推荐

