@Test void whenExceptionOccursBeforeRequest_exceptionHandlerIsCalled() { doThrow(new RuntimeException("Broken")).when(this.interceptor) .accept(any(RequestSpecification.class)); this.targetMethodDefinition.returnType(Response.class) .uri("/resources/{name}") .method(HttpMethod.GET) .templateParameter(0, new SimpleTemplateParameter("name")) .readTimeout(1000) .body(1); TargetMethodDefinition methodDefinition = this.targetMethodDefinition.build(); TargetMethodHandler targetMethodHandler = new BlockingTargetMethodHandler( methodDefinition, this.encoder, Collections.singletonList(this.interceptor), this.client, this.decoder, this.exceptionHandler, this.executor, this.logger, this.retry); assertThrows(RuntimeException.class, () -> targetMethodHandler.execute(Arrays.array("name"))); verifyZeroInteractions(this.client, this.decoder); verify(this.exceptionHandler, times(1)).apply(any(Throwable.class)); }
@Override public Object execute(final Object[] arguments) { final RequestSpecification requestSpecification = this.resolve(arguments); CompletableFuture<Object> result = CompletableFuture.runAsync(() -> intercept(requestSpecification), this.executor) .thenRunAsync(() -> encode(requestSpecification, arguments), this.executor) .thenApplyAsync(nothing -> requestSpecification.build(), this.executor) .thenApplyAsync(this::request, this.executor) .handleAsync((response, throwable) -> { if (throwable != null) { log.error("Error occurred during method processing. " + "Passing to Exception Handler. Exception: {}: {}", throwable.getClass().getSimpleName(), throwable.getMessage()); throw exceptionHandler.apply(throwable); } else { try { return decode(response); } catch (Exception ex) { log.error("Error occurred processing the response. Passing to Exception Handler." + " Exception: {} {}", ex.getClass().getSimpleName(), ex.getMessage()); throw exceptionHandler.apply(ex); } } }, this.executor); return this.handleResponse(result); }
AbstractTargetMethodHandler implements TargetMethodHandler { @Override public Object execute(final Object[] arguments) { final RequestSpecification requestSpecification = this.resolve(arguments); CompletableFuture<Object> result = CompletableFuture.runAsync(() -> intercept(requestSpecification), this.executor) .thenRunAsync(() -> encode(requestSpecification, arguments), this.executor) .thenApplyAsync(nothing -> requestSpecification.build(), this.executor) .thenApplyAsync(this::request, this.executor) .handleAsync((response, throwable) -> { if (throwable != null) { log.error("Error occurred during method processing. " + "Passing to Exception Handler. Exception: {}: {}", throwable.getClass().getSimpleName(), throwable.getMessage()); throw exceptionHandler.apply(throwable); } else { try { return decode(response); } catch (Exception ex) { log.error("Error occurred processing the response. Passing to Exception Handler." + " Exception: {} {}", ex.getClass().getSimpleName(), ex.getMessage()); throw exceptionHandler.apply(ex); } } }, this.executor); return this.handleResponse(result); } }
AbstractTargetMethodHandler implements TargetMethodHandler { @Override public Object execute(final Object[] arguments) { final RequestSpecification requestSpecification = this.resolve(arguments); CompletableFuture<Object> result = CompletableFuture.runAsync(() -> intercept(requestSpecification), this.executor) .thenRunAsync(() -> encode(requestSpecification, arguments), this.executor) .thenApplyAsync(nothing -> requestSpecification.build(), this.executor) .thenApplyAsync(this::request, this.executor) .handleAsync((response, throwable) -> { if (throwable != null) { log.error("Error occurred during method processing. " + "Passing to Exception Handler. Exception: {}: {}", throwable.getClass().getSimpleName(), throwable.getMessage()); throw exceptionHandler.apply(throwable); } else { try { return decode(response); } catch (Exception ex) { log.error("Error occurred processing the response. Passing to Exception Handler." + " Exception: {} {}", ex.getClass().getSimpleName(), ex.getMessage()); throw exceptionHandler.apply(ex); } } }, this.executor); return this.handleResponse(result); } protected  AbstractTargetMethodHandler(
      TargetMethodDefinition targetMethodDefinition, RequestEncoder encoder,
      List<RequestInterceptor> interceptors, Client client, ResponseDecoder decoder,
      ExceptionHandler exceptionHandler, Executor executor, Logger logger,
      Retry retry); }
AbstractTargetMethodHandler implements TargetMethodHandler { @Override public Object execute(final Object[] arguments) { final RequestSpecification requestSpecification = this.resolve(arguments); CompletableFuture<Object> result = CompletableFuture.runAsync(() -> intercept(requestSpecification), this.executor) .thenRunAsync(() -> encode(requestSpecification, arguments), this.executor) .thenApplyAsync(nothing -> requestSpecification.build(), this.executor) .thenApplyAsync(this::request, this.executor) .handleAsync((response, throwable) -> { if (throwable != null) { log.error("Error occurred during method processing. " + "Passing to Exception Handler. Exception: {}: {}", throwable.getClass().getSimpleName(), throwable.getMessage()); throw exceptionHandler.apply(throwable); } else { try { return decode(response); } catch (Exception ex) { log.error("Error occurred processing the response. Passing to Exception Handler." + " Exception: {} {}", ex.getClass().getSimpleName(), ex.getMessage()); throw exceptionHandler.apply(ex); } } }, this.executor); return this.handleResponse(result); } protected  AbstractTargetMethodHandler(
      TargetMethodDefinition targetMethodDefinition, RequestEncoder encoder,
      List<RequestInterceptor> interceptors, Client client, ResponseDecoder decoder,
      ExceptionHandler exceptionHandler, Executor executor, Logger logger,
      Retry retry); @Override Object execute(final Object[] arguments); }
AbstractTargetMethodHandler implements TargetMethodHandler { @Override public Object execute(final Object[] arguments) { final RequestSpecification requestSpecification = this.resolve(arguments); CompletableFuture<Object> result = CompletableFuture.runAsync(() -> intercept(requestSpecification), this.executor) .thenRunAsync(() -> encode(requestSpecification, arguments), this.executor) .thenApplyAsync(nothing -> requestSpecification.build(), this.executor) .thenApplyAsync(this::request, this.executor) .handleAsync((response, throwable) -> { if (throwable != null) { log.error("Error occurred during method processing. " + "Passing to Exception Handler. Exception: {}: {}", throwable.getClass().getSimpleName(), throwable.getMessage()); throw exceptionHandler.apply(throwable); } else { try { return decode(response); } catch (Exception ex) { log.error("Error occurred processing the response. Passing to Exception Handler." + " Exception: {} {}", ex.getClass().getSimpleName(), ex.getMessage()); throw exceptionHandler.apply(ex); } } }, this.executor); return this.handleResponse(result); } protected  AbstractTargetMethodHandler(
      TargetMethodDefinition targetMethodDefinition, RequestEncoder encoder,
      List<RequestInterceptor> interceptors, Client client, ResponseDecoder decoder,
      ExceptionHandler exceptionHandler, Executor executor, Logger logger,
      Retry retry); @Override Object execute(final Object[] arguments);  }