Reputation: 67
I am receiving a request in a 0.RestController
and give it to the service for processing. If service doesnt throw exception
, i just return HttpStatus.200
, but if an exception occurs in the service, i need catch it in controller and return the status depending on the exception.
Inside service, i need to use Mono.fromCallable
for repo access. Well, if user not found, i try throw my CustomException
, but i cant cach it in controller. What am I doing wrong?
Controller:
@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!");
}
My service:
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));
}
}
}
My CustomException:
@AllArgsConstructor
@Getter
public class CheckCardStatusException extends RuntimeException {
private HttpStatus httpStatus;
}
Upvotes: 0
Views: 344
Reputation: 6255
The Mono
returned by checkCardStatus
is never subscribed, so the error signal is ignored. You have to return the whole chain to the Webflux framework as follows:
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)));
}
In case of an error, the corresponding ExceptionHandler
will be executed.
Upvotes: 2