通过错误处理信息增强单声道

问题描述 投票:0回答:1

我们正在使用

Mono
来处理调用 REST 服务,我想通过添加一些额外的信息来增强异常处理,以便在必须抛出异常时使用。

粗略地说,我们的代码是这样的形式:

public ResultType callSomeService(Object param) {
   return addTimeoutAndRetryToMono(getMonoForServiceCall(param)).block();
}

addTimeoutAndRetryToMono
是一个函数,它接受并返回
Mono
并添加超时、重试和错误映射。例如,它在错误映射中定义了我们抛出一个
TimeoutException

我想通过有关正在调用的服务的信息来增强

callSomeService
函数抛出的异常。例如,我想抛出一个自定义异常,并带有“调用 {some path} 时超时”之类的消息。

不幸的是,“路径”信息仅在

getMonoForServiceCall
中可用,它是基于OpenAPI规范生成的。

我将上面提到的功能简化为:

Mono<T> getMonoForServiceCall(Object param) {
   ....
   // webClient comes from spring-webflux
   // prepareRequest handles the http method, path, query params, etc., fairly boiler-plate stuff
   ...
   WebClient.RequestBodySpec requestBuilder = prepareRequest(webClient, path, param);

   return requestBuilder.retrieve().bodyToMono(returnType);
}

Mono<T> addTimeoutAndRetryToMono(Mono<T> mono) {
  return mono.timeout(Duration.ofSeconds(10))
             .onErrorMap(t -> handleExceptions(t));
}

Throwable handleExceptions(Throwable t) {
  return new RestClientException("Here I would like to have the path of the API being called");
}

最简单的方法是传递“路径”信息,在

callSomeService
中捕获并抛出自定义异常,但是这些方法相当多,而且确实感觉“肮脏”。

我尝试在

contextWrite
中使用
getMonoForService
,将“路径”添加到上下文中,但我似乎无法在错误图中使用它。

理想的更改将在

getMonoForService
(我可以访问路径和其他相关字段)和
addTimeoutAndRetryToMono
(添加错误映射)级别进行,因为它们位于共享库之一中并会产生更清洁的解决方案。
getMonoForServiceCall
函数应继续返回
Mono<T>

java spring-webflux reactive-programming project-reactor
1个回答
0
投票

对于任何感兴趣的人,我设法解决了这个问题。

数据在

Mono
系统中流动的方式是,您在订阅
Mono
时(即调用
block
时)提供“上下文”。然后,上下文由
Mono
的各个层读取和处理,可能会影响最终结果。

我需要的是数据向后流动:底层,即进行实际 REST 调用的层,拥有我需要的

path
信息,并且我需要在调用
block
的方法中访问它。

当然,最简单的方法是让处理 REST 调用的层在组合对象中返回结果对象和路径。就我而言,这是不可接受的,因为这意味着破坏几个依赖库中的向后兼容性和代码更改。

为了使用

context
作为
path
数据的侧通道,我使用了“容器对象”。我使用
contextWrite
在上下文中添加此对象,在最终调用
block
的方法中。然后,在我可以访问“路径”的地方,我使用
deferContextual
来改变“容器对象”并存储路径。

一旦

block
方法完成,我就可以查看“容器对象”内部并检索路径。

© www.soinside.com 2019 - 2024. All rights reserved.