In my request handler, if the passed-in accountId cannot be converted to a valid ObjectId I want to catch the error and send back a meaningful message; however, doing so causes the return type to be incompatible, and I cannot figure out how to achieve this pretty trivial use case.
My code:
  @GetMapping("/{accountId}")
  public Mono<ResponseEntity<Account>> get(@PathVariable String accountId) {
      log.debug(GETTING_DATA_FOR_ACCOUNT, accountId);
      try {
        ObjectId id = new ObjectId(accountId);
        return repository.findById(id)
            .map(ResponseEntity::ok)
            .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
      } catch (IllegalArgumentException ex) {
        log.error(MALFORMED_OBJECT_ID, accountId);
        // TODO(marco): find a way to return the custom error message. This seems to be currently
        //  impossible with the Reactive API, as using body(message) changes the return type to
        //  be incompatible (and Mono<ResponseEntity<?>> does not seem to cut it).
        return Mono.just(ResponseEntity.badRequest().build());
      }
  }
The body(T body) method changes the type of the returned Mono so that it is (assuming one just sends a String) a Mono<ResponseEntity<String>>; however, changing the method's return type to Mono<ResponseEntity<?>> does not work either:
        ...
        return Mono.just(ResponseEntity.badRequest().body(
            MALFORMED_OBJECT_ID.replace("{}", accountId)));
as it gives an "incompatible type" error on the other return statement:
error: incompatible types: Mono<ResponseEntity<Account>> cannot be converted to Mono<ResponseEntity<?>>
            .switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
Obviously, changing the return type of the method to Mono<?> would work, but the response then is the serialized JSON of the ResponseEntity which is NOT what I want.
I have also tried using the onErrorXxxx() methods, but they do not work here either, as the conversion error happens even before the Flux is computed, and I just get a "vanilla" 400 error with an empty message.
The only way I can think of working around this would be to add a message field to my Account object and return that one, but it's genuinely a horrible hack.