如何将 CustomException 从反应式服务抛出到控制器?
How throws CustomException from reactive service to controller?
我在 0.RestController
中收到一个请求,并将其交给服务进行处理。如果服务没有抛出 exception
,我只是 return HttpStatus.200
,但是如果服务中发生异常,我需要在控制器中捕获它并且 return 状态取决于异常.
在服务内部,我需要使用 Mono.fromCallable
进行回购访问。好吧,如果找不到用户,我会尝试抛出我的 CustomException
,但我无法将其缓存在控制器中。我做错了什么?
控制器:
@RestController
@RequiredArgsConstructor
@Slf4j
public class CardStatusController {
private final CardStatusService cardStatusService;
@PostMapping(value = "api/{user_id}/confirm", produces = {MediaType.APPLICATION_JSON_VALUE})
public Mono<ResponseEntity<HttpStatus>> confirmStatus(
@PathVariable("user_id") String userId,
@RequestBody CardStatusRequest statusRequest) {
statusRequest.setUserId(userId);
cardStatusService.checkCardStatus(statusRequest);
return Mono.just(new ResponseEntity<>(HttpStatus.OK));
}
@ExceptionHandler({ CheckCardStatusException.class })
public void handleException() {
log.error("error!");
}
我的服务:
public Mono<Void> checkCardStatus(CardStatusRequest statusRequest) throws CheckCardStatusException {
if (statusRequest.getCardEmissionStatus().equals(CardEmissionStatus.ACCEPTED)) {
String reference = statusRequest.getReference();
return Mono.fromCallable(() -> userRepository.findById(statusRequest.getUserId()))
.subscribeOn(Schedulers.boundedElastic())
.switchIfEmpty(Mono.error(new CheckCardStatusException(HttpStatus.NOT_FOUND)))
.flatMap(user -> Mono.fromCallable(() -> cardRepository.findFireCardByUserId(user.getId()))
.flatMap(optionalCard -> {
if (optionalCard.isPresent()) {
if (optionalCard.get().getExtId().isEmpty()) {
Card card = optionalCard.get();
card.setExtId(reference);
try {
cardRepository.save(card);
} catch (Exception e) {
return Mono.error(new CheckCardStatusException(HttpStatus.INTERNAL_SERVER_ERROR));
}
} else {
if (!optionalCard.get().getExtId().equals(reference)) {
return Mono.error(new CheckCardStatusException(HttpStatus.CONFLICT));
}
}
} else {
Card card = new Card();
//set card params
try {
cardRepository.save(card);
} catch (Exception e) {
return Mono.error(new CheckCardStatusException(HttpStatus.INTERNAL_SERVER_ERROR));
}
}
return Mono.error(new CheckCardStatusException(HttpStatus.OK));
})).then();
}
else {
return Mono.error(new CheckCardStatusException(HttpStatus.OK));
}
}
}
我的自定义异常:
@AllArgsConstructor
@Getter
public class CheckCardStatusException extends RuntimeException {
private HttpStatus httpStatus;
}
由 checkCardStatus
编辑的 Mono
return 从未被订阅,因此错误信号被忽略。您必须 return 整个链到 Webflux 框架如下:
public Mono<ResponseEntity<HttpStatus>> confirmStatus(
@PathVariable("user_id") String userId,
@RequestBody CardStatusRequest statusRequest) {
statusRequest.setUserId(userId);
return cardStatusService.checkCardStatus(statusRequest)
.then(Mono.just(new ResponseEntity<>(HttpStatus.OK)));
}
如果出错,会执行相应的ExceptionHandler
。
我在 0.RestController
中收到一个请求,并将其交给服务进行处理。如果服务没有抛出 exception
,我只是 return HttpStatus.200
,但是如果服务中发生异常,我需要在控制器中捕获它并且 return 状态取决于异常.
在服务内部,我需要使用 Mono.fromCallable
进行回购访问。好吧,如果找不到用户,我会尝试抛出我的 CustomException
,但我无法将其缓存在控制器中。我做错了什么?
控制器:
@RestController
@RequiredArgsConstructor
@Slf4j
public class CardStatusController {
private final CardStatusService cardStatusService;
@PostMapping(value = "api/{user_id}/confirm", produces = {MediaType.APPLICATION_JSON_VALUE})
public Mono<ResponseEntity<HttpStatus>> confirmStatus(
@PathVariable("user_id") String userId,
@RequestBody CardStatusRequest statusRequest) {
statusRequest.setUserId(userId);
cardStatusService.checkCardStatus(statusRequest);
return Mono.just(new ResponseEntity<>(HttpStatus.OK));
}
@ExceptionHandler({ CheckCardStatusException.class })
public void handleException() {
log.error("error!");
}
我的服务:
public Mono<Void> checkCardStatus(CardStatusRequest statusRequest) throws CheckCardStatusException {
if (statusRequest.getCardEmissionStatus().equals(CardEmissionStatus.ACCEPTED)) {
String reference = statusRequest.getReference();
return Mono.fromCallable(() -> userRepository.findById(statusRequest.getUserId()))
.subscribeOn(Schedulers.boundedElastic())
.switchIfEmpty(Mono.error(new CheckCardStatusException(HttpStatus.NOT_FOUND)))
.flatMap(user -> Mono.fromCallable(() -> cardRepository.findFireCardByUserId(user.getId()))
.flatMap(optionalCard -> {
if (optionalCard.isPresent()) {
if (optionalCard.get().getExtId().isEmpty()) {
Card card = optionalCard.get();
card.setExtId(reference);
try {
cardRepository.save(card);
} catch (Exception e) {
return Mono.error(new CheckCardStatusException(HttpStatus.INTERNAL_SERVER_ERROR));
}
} else {
if (!optionalCard.get().getExtId().equals(reference)) {
return Mono.error(new CheckCardStatusException(HttpStatus.CONFLICT));
}
}
} else {
Card card = new Card();
//set card params
try {
cardRepository.save(card);
} catch (Exception e) {
return Mono.error(new CheckCardStatusException(HttpStatus.INTERNAL_SERVER_ERROR));
}
}
return Mono.error(new CheckCardStatusException(HttpStatus.OK));
})).then();
}
else {
return Mono.error(new CheckCardStatusException(HttpStatus.OK));
}
}
}
我的自定义异常:
@AllArgsConstructor
@Getter
public class CheckCardStatusException extends RuntimeException {
private HttpStatus httpStatus;
}
由 checkCardStatus
编辑的 Mono
return 从未被订阅,因此错误信号被忽略。您必须 return 整个链到 Webflux 框架如下:
public Mono<ResponseEntity<HttpStatus>> confirmStatus(
@PathVariable("user_id") String userId,
@RequestBody CardStatusRequest statusRequest) {
statusRequest.setUserId(userId);
return cardStatusService.checkCardStatus(statusRequest)
.then(Mono.just(new ResponseEntity<>(HttpStatus.OK)));
}
如果出错,会执行相应的ExceptionHandler
。