繁体   English   中英

在Spring Web Flux中捕获异常

[英]Catching exceptions in Spring Web Flux

我有以下用于通过Web服务调用耗时的操作的类:

@Service
public class InferenceService {

    @Autowired
    private final WebClient inferenceClient;

    public ByteArrayResource invoke(FileSystemResource resource) throws HttpException {
        Mono<ByteArrayResource> mono = inferenceClient
                .post()
                .uri(INFERENCE_URI)
                .contentType(MediaType.valueOf("application/zip"))
                .body(BodyInserters.fromResource(resource))
                .accept()
                .retrieve()
                .bodyToMono(ByteArrayResource.class);

        ByteArrayResource zip = mono.block();
        return zip;
    }
}

如果在Web服务调用期间发生异常(如UnknownHostException),则将异常包装在ReactiveException中。 我希望我的类捕获原始异常并将其作为HttpException重新抛出,以便能够对其进行记录,由Spring异常处理程序处理,从我的控制器返回500状态并且不难理解带有抑制异常的stacktrace在我的日志中。 我写了这样的东西:

@Service
public class InferenceService {

    @Autowired
    private final WebClient inferenceClient;

    public ByteArrayResource invoke(FileSystemResource resource) throws HttpException {
        Mono<ByteArrayResource> mono = inferenceClient
                .post()
                .uri(INFERENCE_URI)
                .contentType(MediaType.valueOf("application/zip"))
                .body(BodyInserters.fromResource(resource))
                .accept()
                .retrieve()
                .onStatus(HttpStatus::is5xxServerError, this::getStatus500Error)
                .bodyToMono(ByteArrayResource.class);

        try {
            ByteArrayResource zip = mono.block();
            return zip;
        } catch (RuntimeException e) {
            throw extractFromReactiveException(e);
        }
    }

    private Mono<? extends Throwable> getStatus500Error(ClientResponse clientResponse) {
        return Mono.error(new InternalServerError(getStatusErrorMsg(clientResponse)));
    }

    private HttpException extractFromReactiveException(RuntimeException e) {
        if (e.getCause() instanceof HttpException) {
            return (HttpException) e.getCause();
        } else {
            return new InternalServerError(e);
        }
    }
}

但是我觉得要么有更好的方法,要么我想实现的目标是错误的。 正确的方法是什么?

您永远不要使用块。 反应堆的目的是处理链中的所有东西。 因此,您的方法应返回一个Mono而不是对象本身。

如果要更改异常,则应使用.onErrorMap(throwable-> extractFromReactiveException(throwable)); 在bodyToMono之后。

并使extract方法返回HttpException而不是Mono。

这是文档,查找onErrorMap方法及其重载。 https://projectreactor.io/docs/core/release/api/

随时询问您是否还有任何疑问!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM