如何捕获阻塞 webclient GET 请求的 onStatus 方法中抛出的异常?

cjw*_*s48 10 java spring spring-webflux

我现在正在使用 WebClient 而不是 rest 模板来调用 API。目标是在不久的将来 sprint 中,我们将使我们所有的客户端都具有响应性和非阻塞性,但在短期内,我们可以使用阻塞调用,但至少有 WebClient 到位。我们想要做的一件事是在返回 204 No Content 状态时抛出自定义异常,以便使用客户端的代码必须捕获异常

我曾尝试从 抛出异常.onStatus(...),但发生的情况是它不会PersonNotFoundException从下面的代码中抛出 ,而是抛出reactor.core.Exceptions$ReactiveException带有PersonNotFoundException嵌套的

客户端代码

public PersonDto getPersonDetails(String lastName) throws PersonNotFoundException{
    return webClient.get()
              .uri(personEndpoint + "/{lastName}", lastName)
              .retrieve()
              .onStatus(status -> status.equals(HttpStatus.NO_CONTENT),
                            clientResponse -> Mono.error(new PersonNotFoundException("Person " + lastName + "Not Found")))
              .bodyToMono(PersonDto.class)
              .block();
}
Run Code Online (Sandbox Code Playgroud)

呼叫代码

 PersonDto personDto = null;
 try {
    personDto = personServiceCLient.getPersonDetails("Smith");
 } catch (PersonNotFoundException e) {
    //do custom logic for 204 errors
 }
Run Code Online (Sandbox Code Playgroud)

我希望的结果是PersonNotFoundException将在调用代码的 catch 语句中被捕获。结果是抛出了一个 ReactiveException,未捕获的异常终止了我的程序:

reactor.core.Exceptions$ReactiveException: com.sample.demo.PersonNotFoundException: Person Smith Not Found
    at reactor.core.Exceptions.propagate(Exceptions.java:326) ~[reactor-core-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:91) ~[reactor-core-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at reactor.core.publisher.Mono.block(Mono.java:1494) ~[reactor-core-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at com.sample.demo.client.PersonServiceClient.getPersonDetails(PersonServiceClient.java.java:45) ~[classes/:na]
    at com.sample.demo.PersonServiceImpl.addPersonToHousehold(PersonServiceImpl.java:120) ~[classes/:na]
Run Code Online (Sandbox Code Playgroud)

小智 5

您的自定义异常PersonNotFoundException被包装到 reactor.core.Exceptions$ReactiveException. 为了避免这种情况,请始终使用RuntimeException. 现在您必须从RuntimeException.

例如:

public class PersonNotFoundException extends RuntimeException
Run Code Online (Sandbox Code Playgroud)


小智 -3

尝试使用 Exceptions util 类。现在可能为时已晚,但是哦,好吧。

public PersonDto getPersonDetails(String lastName) throws PersonNotFoundException{
return webClient.get()
          .uri(personEndpoint + "/{lastName}", lastName)
          .retrieve()
          .onStatus(status -> status.equals(HttpStatus.NO_CONTENT),
                        clientResponse -> throw Exceptions.propagate(new PersonNotFoundException("Person " + lastName + "Not Found")))
          .bodyToMono(PersonDto.class)
          .block();
Run Code Online (Sandbox Code Playgroud)

}

  • 似乎不是一个有效的解决方案。产生:令牌“抛出”上的语法错误 (3认同)