Spring WebClient聚合多个401 UNAUTHORIZED错误抛出exception . composit



当WebClient使用错误的令牌异步调用外部api(使用不同的查询参数)时,前几个返回401 UNAUTHORIZED,控制流终止于Exceptions.CompositeException。我们在WebClient实例中添加了如下过滤器,检查4xx和5xx响应状态码以抛出自定义异常

private final ExchangeFilterFunction responseFilter() {
return ExchangeFilterFunction
.ofResponseProcessor(response -> response.statusCode().isError() ? error(() -> new CustomException("API Error")) : just(response));
private WebClient buildWebClient(WebClient.Builder builder) {
return builder
.filter(responseFilter())
.build();
}

现在的问题是CustomException不会被抛出时,第一次调用返回一个错误(401),而是聚集一堆调用和抛出Exceptions.CompositeException。在日志中,我们可以看到在Composite失败之前至少有3或4个401 UNAUTHORIZED。当第一个失败时,它不会抛出预期的CustomException。这个WebClient调用发生在Flux.zip内,我不确定这是否与问题有关。

当使用任何DelayError变体操作符时,反应器将收集任何异常(如果有多于1)到CompositeException

Reactor提供了一个实用方法Exceptions.unwrapMultiple,如果你只想在上游传播一个子集或单个错误,它可以帮助你将一个复合异常解包到一个throwables列表中——java docs

Exceptions.unwrapMultiple

尝试将一个Throwable展开到一个Throwables列表中。只有在上述Throwable是由多个(Throwable…)构建的复合异常的条件下才会执行此操作,在这种情况下,列表中包含作为抑制异常包装在复合中的异常。在任何其他情况下,列表只包含输入Throwable(或者在null输入的情况下为空)。

示例

下面是一个使用unwrapMultipleCompositeException中只传播第一个Throwable的小示例。

Flux<Object> range = Flux.range(1, 10)
.flatMapDelayError(i -> Mono.error(new IllegalArgumentException(String.format("Error: %s", i))), 10, 1)
.onErrorResume(throwable -> Mono.error(Exceptions.unwrapMultiple(throwable).get(0)));
StepVerifier.create(range)
.expectError(IllegalArgumentException.class)
.verify();

相关内容

最新更新