@Override
    public CompletableFuture<T> execute() {
        if (delegate.exchangeType() == null) {
            final boolean requestStreaming = delegate.isRequestStreaming();
            final boolean responseStreaming = !responseAs.requiresAggregation();
            exchangeType(ExchangeType.of(requestStreaming, responseStreaming));
        }

        CompletableFuture<T> response;
        try {
            response = responseAs.as(delegate.execute());
        } catch (Exception ex) {
            response = new CompletableFuture<>();
            response.completeExceptionally(ex);
        }

        if (errorHandler == null) {
            return response;
        }

        return response.exceptionally(cause -> {
            cause = Exceptions.peel(cause);
            assert errorHandler != null;
            final Object maybeRecovered = errorHandler.apply(cause);
            if (maybeRecovered instanceof Throwable) {
                // The cause was translated.
                return Exceptions.throwUnsafely((Throwable) maybeRecovered);
            }
            if (maybeRecovered != null) {
                //noinspection unchecked
                return (T) maybeRecovered;
            }
            // Not handled.
            return Exceptions.throwUnsafely(cause);
        });
    }
Prepares and executes a new {@link HttpRequest} for {@link WebClient}, and asynchronously transforms an
{@link HttpResponse} into a {@code T} type object.
core/src/main/java/com/linecorp/armeria/client/FutureTransformingRequestPreparation.java