1

I had a sense from tutorials that returning a throwable, shouldn't change method return type.

Here are my tries:

  1. When using handle, everything is fine until I add .timeout(), then function return type is changed to Flux<Object>
private Flux<String> exampleHandle()
{
    MutableHttpRequest<String> req = HttpRequest.GET("http://localhost:8080");

    return httpClient.exchange(req, TokenResponse.class)
        .handle((response, sink) -> {
            Optional<TokenResponse> optionalBody = response.getBody();
            if (optionalBody.isEmpty()) {
                sink.error(new InitializationException("Failed to fetch authentication token. Body is null."));
            } else {
                TokenResponse tokenResponse = optionalBody.get();
                String accessToken = tokenResponse.getAccessToken();
                if (accessToken != null) {
                    sink.next(accessToken);
                } else {
                    sink.error(new InitializationException("Failed to fetch authentication token. Authentication token is null."));
                }
            }
        });
       // .timeout(Duration.ofSeconds(10)); // Timeout changes return type to Flux<Object>
}
  1. When using map and Flux.error (i tried Mono.error also), function return type is changed to Flux<Object> when I introduce Flux.error in map
private Flux<String> exampleMap()
{
    MutableHttpRequest<String> req = HttpRequest.GET("http://localhost:8080");

    return httpClient.exchange(req, TokenResponse.class)
        .map(response -> {
            Optional<TokenResponse> optionalBody = response.getBody();
            if (optionalBody.isEmpty()) {
                return Flux.error(new InitializationException("Failed to fetch authentication token. Body is null."));
            } else {
                TokenResponse tokenResponse = optionalBody.get();
                String accessToken = tokenResponse.getAccessToken();
                if (accessToken != null) {
                    return accessToken;
                } else {
                    return Flux.error(new InitializationException("Failed to fetch authentication token. Authentication token is null."));
                }
            }
        });
}

Can someone more knowledgeable explain me what am I doing wrong? Thank you!

message
  • 4,513
  • 2
  • 28
  • 39
  • 1
    If your Flux times out, then it cannot return a string, I guess that's why it changes to Object. When you map, you shouldn't return the container type (that's what flatMap is for) – knittl Dec 22 '21 at 20:01
  • 1
    Are you confusing _throwing_ an `Exception` with returning it? They're not the same thing. When you return something from a method, control is passed to the method that called your one. When you throw something, control is passed to a `catch` clause, which might be several steps down the stack. – Dawood ibn Kareem Dec 22 '21 at 20:40

1 Answers1

0

You should move timeout before handle:

 return httpClient.exchange(req, TokenResponse.class)
        .timeout(Duration.ofSeconds(10))
        .handle((response, sink) -> {

As for the map case, take a look at the method signature:

Flux map(Function<? super T,? extends V> mapper)

map takes a Function<T, U> and returns a Flux<U>, returning Flux.error is invalid. You could simply use throw inside map and Reactor will turn it into a proper error signal but I think handle fits better in this case.

Useful links:

lkatiforis
  • 5,703
  • 2
  • 16
  • 35