CircuitBreakerImpl implements CircuitBreaker<ET>, CircuitBreaker.ManualModeTask<ET> { protected Throwable unwrapAsyncExceptions(Throwable error) { if (error == null || error.getCause() == null) return error; if (error instanceof CompletionException || error instanceof ExecutionException) { error = error.getCause(); error = unwrapAsyncExceptions(error); } return error; } CircuitBreakerImpl();  CircuitBreakerImpl(Optional<ScheduledExecutorService> scheduler,
                              Optional<ExecutorService> stateChangeNotificationExecutor,
                              Optional<Integer> maxConsecutiveFailuresAllowed,
                              Optional<Duration> resetTimeout,
                              Optional<Duration> callTimeout,
                              Optional<String> id,
                              Optional<BreakingEventStrategy<ET>> breakingEventStrategy,
                              Optional<BreakingExceptionStrategy> breakingExceptionStrategy); static Builder<E> newBuilder(); static Builder<E> newBuilder(BreakingEventStrategy<E> breakingEventStrategy); @Override ManualModeTask<ET> newManualModeTask(); @Override void throwExceptionIfCircuitBreakerIsOpen(); @Override void handleEvent(ET event); @Override void handleException(Throwable throwable); @Override CircuitBreaker<ET> originatingCircuitBreaker(); @Override CompletableFuture<ET> executeAsyncCall(Supplier<CompletableFuture<ET>> eventFutureSupplier); @Override ET executeBlockingCall(Callable<ET> eventSupplier); @Override CircuitBreakerImpl<ET> onClose(Runnable listener); @Override CircuitBreakerImpl<ET> onHalfOpen(Runnable listener); @Override CircuitBreakerImpl<ET> onOpen(Runnable listener); @Override String getId(); static final String DEFAULT_MAX_CONSECUTIVE_FAILURES_ALLOWED_SYSTEM_PROP_KEY; static final String DEFAULT_RESET_TIMEOUT_SECONDS_SYSTEM_PROP_KEY; static final int DEFAULT_MAX_CONSECUTIVE_FAILURES_ALLOWED; static final long DEFAULT_RESET_TIMEOUT_SECONDS; static final int FALLBACK_DEFAULT_MAX_CONSECUTIVE_FAILURES_ALLOWED; static final long FALLBACK_DEFAULT_RESET_TIMEOUT_SECONDS; static final BreakingEventStrategy<?> DEFAULT_BREAKING_EVENT_STRATEGY; static final BreakingExceptionStrategy DEFAULT_BREAKING_EXCEPTION_STRATEGY; }
@Test public void unwrapAsyncExceptions_returns_null_if_passed_null() { assertThat(cbSpy.unwrapAsyncExceptions(null)).isNull(); }
@Test public void unwrapAsyncExceptions_returns_passed_in_arg_if_exception_has_no_cause() { Exception noCause = new Exception("boom"); assertThat(cbSpy.unwrapAsyncExceptions(noCause)).isSameAs(noCause); }
@Test public void unwrapAsyncExceptions_unwraps_CompletionException() { Exception underlyingError = new Exception("bang"); CompletionException wrapperEx = new CompletionException(underlyingError); assertThat(cbSpy.unwrapAsyncExceptions(wrapperEx)).isSameAs(underlyingError); }
@Test public void unwrapAsyncExceptions_unwraps_ExecutionException() { Exception underlyingError = new Exception("bang"); ExecutionException wrapperEx = new ExecutionException(underlyingError); assertThat(cbSpy.unwrapAsyncExceptions(wrapperEx)).isSameAs(underlyingError); }
@Test public void unwrapAsyncExceptions_unwraps_recursively() { Exception underlyingError = new Exception("bang"); ExecutionException wrapperEx = new ExecutionException(underlyingError); CompletionException doubleWrapperEx = new CompletionException(wrapperEx); assertThat(cbSpy.unwrapAsyncExceptions(doubleWrapperEx)).isSameAs(underlyingError); }
@Test public void unwrapAsyncExceptions_returns_passed_in_arg_if_exception_has_cause_but_is_not_unwrappable() { Exception wrapperEx = new Exception(new Exception("boom")); assertThat(cbSpy.unwrapAsyncExceptions(wrapperEx)).isSameAs(wrapperEx); }