Felipe
Felipe

Reputation: 7563

How to return bad request in spring webflux when there is an error?

I have this server endpoint using spring-webflux and I would like to return ServerResponse.badRequest() when the serverRequest receives a wrong parameter. The request curl -s "http://localhost:8080/4?a=5&b=3"; echo for instance, contains the right parameters. But the request curl -s "http://localhost:8080/one?a=5&b=3"; echo contains a string instead of an Integer. Then the conversion new BidRequest(Integer.parseInt(tuple2.getT1()), tuple2.getT2().toSingleValueMap()) will throw an error.

I was doing .onErrorReturn(new BidRequest(0, null)) but now I want to implement some operation that return ServerResponse.badRequest(). So I added in the end .onErrorResume(error -> ServerResponse.badRequest().build()) in the end, but It is not working. I also added on the place of the code .onErrorReturn() and it does not compile.

public Mono<ServerResponse> bidRequest(ServerRequest serverRequest) {
    var adId = serverRequest.pathVariable("id");
    var attributes = serverRequest.queryParams();
    log.info("received bid request with adID: {} attributes: {}", adId, attributes);

    return Mono.just(Tuples.of(adId, attributes))
        .map(tuple2 -> new BidRequest(Integer.parseInt(tuple2.getT1()), tuple2.getT2().toSingleValueMap()))
        // I WANT TO REPLACE IT FOR A BAD REQUEST
        // .onErrorReturn(new BidRequest(0, null))
        .flatMap(bidRequest -> {
            return Flux.fromStream(bidderService.bidResponseStream(bidRequest))
                    .flatMap(this::gatherResponses)
                    .reduce((bidResp1, bidResp2) -> {
                        if (bidResp1.getBid() > bidResp2.getBid()) return bidResp1;
                        else return bidResp2;
                    });
        })
        .map(bid -> {
            var price = bid.getContent().replace("$price$", bid.getBid().toString());
            bid.setContent(price);
            return bid;
        })
        .flatMap(winner -> {
            return ServerResponse.ok()
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(BodyInserters.fromValue(winner.getContent()));
        })
        .switchIfEmpty(ServerResponse.notFound().build())
        // THIS DOES NOT RETURN ANY BAD REQUEST
        .onErrorResume(error -> ServerResponse.badRequest().build());
}

Upvotes: 0

Views: 1660

Answers (1)

Felipe
Felipe

Reputation: 7563

I solved based on this answer using flatmap and returning a Mono.just() or a Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST));.

return Mono
        .just(Tuples.of(adId, attributes))
        .flatMap(tuple2 -> {
            if (validate(tuple2)) {
                log.info("request parameters valid: {}", tuple2);
                return Mono.just(new BidRequest(Integer.parseInt(tuple2.getT1()), tuple2.getT2().toSingleValueMap()));
            } else {
                log.error("request parameters invalid: {}", tuple2);
                return Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST));
            }
        })
        .flatMap(....
private boolean validate(Tuple2<String, MultiValueMap<String, String>> tuple2) {
    return GenericValidator.isInteger(tuple2.getT1());
}

Upvotes: 1

Related Questions