我有两个微服务,我们说一个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
?
答案 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客户端优先于阻塞客户端)。