0

I am using WebClient for an API Call in a springboot project. I want to handle retries if the response code is 5xx. When a status code 5xx comes, I want to throw a CustomException. I am handling this exception like below in the method that is calling this API.

@Retryable(
      backoff = @Backoff(delayExpression = "${upload.retry.delay:10000}"),
      maxAttemptsExpression = "${upload.max.retry.limit:3}",
      include = {FileProcessingException.class})

I have a tried a few things, but those don't seem to work.

  1. don't have any effect on the code. It passes and when I do .block, throws NPE.
void getAuthToken(){
authorizationTokenResponse =
          webClient
              .post()
              .uri(apiUrl + LOGIN)
              .contentType(MediaType.APPLICATION_JSON)
              .accept(MediaType.APPLICATION_JSON)
              .bodyValue(gson.toJson(loginRequest))
              .retrieve()
                  .onStatus(HttpStatus::is4xxClientError,
                          response -> response.bodyToMono(String.class).map(FileProcessingException::new))
                  .onStatus(HttpStatus::is5xxServerError,
                          response -> response.bodyToMono(String.class).map(FileProcessingException::new))
                  .bodyToMono(AuthorizationTokenResponse.class)
                  .retry(3);
}
  1. I tried the following : https://stackoverflow.com/questions/58520919/spring-webclient-retry-with-backoff-on-specific-error#:~:text=You%20can%20do%20this%20taking%20the%20following%20approach%3A But I get the compilation error: no instance(s) of type variable(s) R exist so that String conforms to Mono<? extends R>
void getAuthToken() {
.exchange().flatMap(responseFromAPI -> {
                    if(responseFromAPI.statusCode().is5xxServerError() || responseFromAPI.statusCode().is4xxClientError()){
                      return Mono.error(new FileProcessingException());
                    } else {
                      AuthorizationTokenResponse tokenResponse = responseFromAPI.bodyToMono(AuthorizationTokenResponse.class).block();
                      authToken = tokenResponse.getAuthorizationToken();
                      authTokenExpDateTime =
                              LocalDateTime.parse(tokenResponse.getTokenExpirationDateTime(),
                                      DateTimeFormatter.ISO_DATE_TIME);
                      return authToken;
                    }
                  });
}
  1. This is my original code:
void getAuthToken() {
ResponseSpec clientResponse =
          webClient
              .post()
              .uri(apiUrl + LOGIN)
              .contentType(MediaType.APPLICATION_JSON)
              .accept(MediaType.APPLICATION_JSON)
              .bodyValue(gson.toJson(loginRequest))
              .retrieve();
}

Code is throwing NPE when doing below:

responseEntity = Objects.requireNonNull(clientResponse.toEntity(AuthorizationTokenResponse.class).block());

I just want to check if the response code is not 200, throw a CustomException, which I can use for retrying.

Thanks!

Edit 1: I didn't mention that I using CompletableFuture to call getAuthToken(). Below is the code:

listOfLineReadFromFile.stream()
            .map(
                lineReadFromList ->
                    CompletableFuture.runAsync(() -> handleLine(lineReadFromList), executorService))
            .forEach(CompletableFuture::join);

where listOfLineReadFromFileis the list for which authToken() is required.

Abhinash Jha
  • 165
  • 1
  • 3
  • 17

0 Answers0