在 WebFlux for Mono<Void> 中使用 onErrorMap 映射错误

Map Error using onErrorMap in WebFlux for Mono<Void>

我有两个微服务,假设是前端和后端,对于前端,我正在使用 WebFlux 并使用假客户端调用后端服务,如下面的代码示例所示,尽管下面的代码示例有效,但我想要使用 Function 有一个通用的异常处理程序并提供给 onErrorMap

@RestController
@Slf4j
public class MyFrentEndService {

    @Autowired
    private MyBackEndService client;

    @PostMapping(value="/hello", consumes="application/json")
    public Mono<Void> sayHello(@Valid String msg) {
        log.info("Message is {}", msg);
        return Mono.create(sink-> {
            try {
                client.hello(msg);
            }catch (FeignException e) {
                System.out.println(e.status());
                HttpStatus status = e.status() ==0 ? HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
                String message = e.getMessage();
                sink.error(new ResponseStatusException(status, message));
            }
            sink.success();
        });

    }

}

尝试使用 onErrorMap,但出现编译错误,请使用 Mono 而不是 Mono<Void>

@RestController
@Slf4j
public class MyFrentEndService {

    @Autowired
    private MyBackEndService client;

    @PostMapping(value="/hello", consumes="application/json")
    public Mono<Void> sayHello(@Valid String msg) {
        log.info("Message is {}", msg);
        return Mono.fromSupplier(() -> {
                  client.hello(msg);
                  return null;
               }).onErrorMap(e->{
                     HttpStatus status = e.status() ==0 } HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
                     String message = e.getMessage();
                     return new ResponseStatusException(status, message);
                });

    }

}

如何使用onErrorMap?

此错误与运算符 onErrorMap 无关。此代码无法编译,因为编译器无法将方法 Mono.fromSupplier 返回的泛型类型推断为 Void - 您在提供的函数上返回 null。 这应该通过执行以下操作来纠正:

    @PostMapping(value="/hello", consumes="application/json")
    public Mono<Void> sayHello(@Valid String msg) {
        log.info("Message is {}", msg);
        return Mono.<Void>fromSupplier(() -> {
                  client.hello(msg);
                  return null;
               }).onErrorMap(e->{
                     HttpStatus status = e.status() ==0 ? HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
                     String message = e.getMessage();
                     return new ResponseStatusException(status, message);
                });

    }

我认为执行以下操作更为惯用:

    @PostMapping(value="/hello", consumes="application/json")
    public Mono<Void> sayHello(@Valid String msg) {
        log.info("Message is {}", msg);
        return Mono.fromRunnable(() -> {
                  client.hello(msg);
               })
               .then()
               .onErrorMap(e->{
                     HttpStatus status = e.status() ==0 ? HttpStatus.SERVICE_UNAVAILABLE : HttpStatus.valueOf(e.status());
                     String message = e.getMessage();
                     return new ResponseStatusException(status, message);
                });

    }

最后,我建议不要在反应管道内使用阻塞调用,除非你真的必须这样做。 (更喜欢 WebClient 或其他非阻塞 HTTP 客户端,而不是阻塞客户端作为伪装)。