使用WebFlux中的onErrorMap for Mono <void>的地图错误

时间:2019-05-01 09:50:30

标签: spring-boot spring-webflux

我有两个微服务,我们说一个FrontEnd和BackEnd,对于FrontEnd,我使用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

1 个答案:

答案 0 :(得分:1)

此错误与运算符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客户端优先于阻塞客户端)。