Search in sources :

Example 6 with HystrixBadRequestException

use of com.netflix.hystrix.exception.HystrixBadRequestException in project Hystrix by Netflix.

the class HystrixCommand method queue.

/**
 * Used for asynchronous execution of command.
 * <p>
 * This will queue up the command on the thread pool and return an {@link Future} to get the result once it completes.
 * <p>
 * NOTE: If configured to not run in a separate thread, this will have the same effect as {@link #execute()} and will block.
 * <p>
 * We don't throw an exception but just flip to synchronous execution so code doesn't need to change in order to switch a command from running on a separate thread to the calling thread.
 *
 * @return {@code Future<R>} Result of {@link #run()} execution or a fallback from {@link #getFallback()} if the command fails for any reason.
 * @throws HystrixRuntimeException
 *             if a fallback does not exist
 *             <p>
 *             <ul>
 *             <li>via {@code Future.get()} in {@link ExecutionException#getCause()} if a failure occurs</li>
 *             <li>or immediately if the command can not be queued (such as short-circuited, thread-pool/semaphore rejected)</li>
 *             </ul>
 * @throws HystrixBadRequestException
 *             via {@code Future.get()} in {@link ExecutionException#getCause()} if invalid arguments or state were used representing a user failure, not a system failure
 * @throws IllegalStateException
 *             if invoked more than once
 */
public Future<R> queue() {
    /*
         * The Future returned by Observable.toBlocking().toFuture() does not implement the
         * interruption of the execution thread when the "mayInterrupt" flag of Future.cancel(boolean) is set to true;
         * thus, to comply with the contract of Future, we must wrap around it.
         */
    final Future<R> delegate = toObservable().toBlocking().toFuture();
    final Future<R> f = new Future<R>() {

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            if (delegate.isCancelled()) {
                return false;
            }
            if (HystrixCommand.this.getProperties().executionIsolationThreadInterruptOnFutureCancel().get()) {
                /*
                     * The only valid transition here is false -> true. If there are two futures, say f1 and f2, created by this command
                     * (which is super-weird, but has never been prohibited), and calls to f1.cancel(true) and to f2.cancel(false) are
                     * issued by different threads, it's unclear about what value would be used by the time mayInterruptOnCancel is checked.
                     * The most consistent way to deal with this scenario is to say that if *any* cancellation is invoked with interruption,
                     * than that interruption request cannot be taken back.
                     */
                interruptOnFutureCancel.compareAndSet(false, mayInterruptIfRunning);
            }
            final boolean res = delegate.cancel(interruptOnFutureCancel.get());
            if (!isExecutionComplete() && interruptOnFutureCancel.get()) {
                final Thread t = executionThread.get();
                if (t != null && !t.equals(Thread.currentThread())) {
                    t.interrupt();
                }
            }
            return res;
        }

        @Override
        public boolean isCancelled() {
            return delegate.isCancelled();
        }

        @Override
        public boolean isDone() {
            return delegate.isDone();
        }

        @Override
        public R get() throws InterruptedException, ExecutionException {
            return delegate.get();
        }

        @Override
        public R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
            return delegate.get(timeout, unit);
        }
    };
    /* special handling of error states that throw immediately */
    if (f.isDone()) {
        try {
            f.get();
            return f;
        } catch (Exception e) {
            Throwable t = decomposeException(e);
            if (t instanceof HystrixBadRequestException) {
                return f;
            } else if (t instanceof HystrixRuntimeException) {
                HystrixRuntimeException hre = (HystrixRuntimeException) t;
                switch(hre.getFailureType()) {
                    case COMMAND_EXCEPTION:
                    case TIMEOUT:
                        // we don't throw these types from queue() only from queue().get() as they are execution errors
                        return f;
                    default:
                        // these are errors we throw from queue() as they as rejection type errors
                        throw hre;
                }
            } else {
                throw Exceptions.sneakyThrow(t);
            }
        }
    }
    return f;
}
Also used : HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) Future(java.util.concurrent.Future) TimeUnit(java.util.concurrent.TimeUnit) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException)

Example 7 with HystrixBadRequestException

use of com.netflix.hystrix.exception.HystrixBadRequestException in project Hystrix by Netflix.

the class HystrixCommandAspect method methodsAnnotatedWithHystrixCommand.

@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")
public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
    Method method = getMethodFromTarget(joinPoint);
    Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint);
    if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) {
        throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " + "annotations at the same time");
    }
    MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));
    MetaHolder metaHolder = metaHolderFactory.create(joinPoint);
    HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);
    ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ? metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();
    Object result;
    try {
        if (!metaHolder.isObservable()) {
            result = CommandExecutor.execute(invokable, executionType, metaHolder);
        } else {
            result = executeObservable(invokable, executionType, metaHolder);
        }
    } catch (HystrixBadRequestException e) {
        throw e.getCause() != null ? e.getCause() : e;
    } catch (HystrixRuntimeException e) {
        throw hystrixRuntimeExceptionToThrowable(metaHolder, e);
    }
    return result;
}
Also used : HystrixCommand(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand) HystrixCollapser(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) MetaHolder(com.netflix.hystrix.contrib.javanica.command.MetaHolder) ExecutionType(com.netflix.hystrix.contrib.javanica.command.ExecutionType) HystrixInvokable(com.netflix.hystrix.HystrixInvokable) AopUtils.getDeclaredMethod(com.netflix.hystrix.contrib.javanica.utils.AopUtils.getDeclaredMethod) Method(java.lang.reflect.Method) FallbackMethod(com.netflix.hystrix.contrib.javanica.utils.FallbackMethod) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) Around(org.aspectj.lang.annotation.Around)

Example 8 with HystrixBadRequestException

use of com.netflix.hystrix.exception.HystrixBadRequestException in project Hystrix by Netflix.

the class AbstractHystrixCommand method process.

/**
 * Executes an action. If an action has failed and an exception is ignorable then propagate it as HystrixBadRequestException
 * otherwise propagate original exception to trigger fallback method.
 * Note: If an exception occurred in a command directly extends {@link java.lang.Throwable} then this exception cannot be re-thrown
 * as original exception because HystrixCommand.run() allows throw subclasses of {@link java.lang.Exception}.
 * Thus we need to wrap cause in RuntimeException, anyway in this case the fallback logic will be triggered.
 *
 * @param action the action
 * @return result of command action execution
 */
Object process(Action action) throws Exception {
    Object result;
    try {
        result = action.execute();
        flushCache();
    } catch (CommandActionExecutionException throwable) {
        Throwable cause = throwable.getCause();
        if (isIgnorable(cause)) {
            throw new HystrixBadRequestException(cause.getMessage(), cause);
        }
        if (cause instanceof RuntimeException) {
            throw (RuntimeException) cause;
        } else if (cause instanceof Exception) {
            throw (Exception) cause;
        } else {
            // instance of Throwable
            throw new CommandActionExecutionException(cause);
        }
    }
    return result;
}
Also used : HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) CommandActionExecutionException(com.netflix.hystrix.contrib.javanica.exception.CommandActionExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) CommandActionExecutionException(com.netflix.hystrix.contrib.javanica.exception.CommandActionExecutionException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException)

Example 9 with HystrixBadRequestException

use of com.netflix.hystrix.exception.HystrixBadRequestException in project Hystrix by Netflix.

the class AbstractCommand method handleBadRequestByEmittingError.

private Observable<R> handleBadRequestByEmittingError(Exception underlying) {
    Exception toEmit = underlying;
    try {
        long executionLatency = System.currentTimeMillis() - executionResult.getStartTimestamp();
        eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);
        executionResult = executionResult.addEvent((int) executionLatency, HystrixEventType.BAD_REQUEST);
        Exception decorated = executionHook.onError(this, FailureType.BAD_REQUEST_EXCEPTION, underlying);
        if (decorated instanceof HystrixBadRequestException) {
            toEmit = decorated;
        } else {
            logger.warn("ExecutionHook.onError returned an exception that was not an instance of HystrixBadRequestException so will be ignored.", decorated);
        }
    } catch (Exception hookEx) {
        logger.warn("Error calling HystrixCommandExecutionHook.onError", hookEx);
    }
    /*
         * HystrixBadRequestException is treated differently and allowed to propagate without any stats tracking or fallback logic
         */
    return Observable.error(toEmit);
}
Also used : HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) HystrixTimeoutException(com.netflix.hystrix.exception.HystrixTimeoutException)

Example 10 with HystrixBadRequestException

use of com.netflix.hystrix.exception.HystrixBadRequestException in project Hystrix by Netflix.

the class HystrixCommandTest method testExceptionConvertedToBadRequestExceptionInExecutionHookBypassesCircuitBreaker.

@Test
public void testExceptionConvertedToBadRequestExceptionInExecutionHookBypassesCircuitBreaker() {
    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    ExceptionToBadRequestByExecutionHookCommand command = new ExceptionToBadRequestByExecutionHookCommand(circuitBreaker, ExecutionIsolationStrategy.THREAD);
    try {
        command.execute();
        fail("we expect to receive a " + HystrixBadRequestException.class.getSimpleName());
    } catch (HystrixBadRequestException e) {
        // success
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
        fail("We expect a " + HystrixBadRequestException.class.getSimpleName() + " but got a " + e.getClass().getSimpleName());
    }
    assertCommandExecutionEvents(command, HystrixEventType.BAD_REQUEST);
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) CancellationException(java.util.concurrent.CancellationException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Aggregations

HystrixBadRequestException (com.netflix.hystrix.exception.HystrixBadRequestException)16 HystrixRuntimeException (com.netflix.hystrix.exception.HystrixRuntimeException)8 TestCircuitBreaker (com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker)7 ExecutionException (java.util.concurrent.ExecutionException)6 TimeoutException (java.util.concurrent.TimeoutException)6 Test (org.junit.Test)6 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)5 IOException (java.io.IOException)4 CommandActionExecutionException (com.netflix.hystrix.contrib.javanica.exception.CommandActionExecutionException)2 HystrixTimeoutException (com.netflix.hystrix.exception.HystrixTimeoutException)2 ByteBuf (io.netty.buffer.ByteBuf)2 HashMap (java.util.HashMap)2 Observable (rx.Observable)2 Action0 (rx.functions.Action0)2 Func1 (rx.functions.Func1)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 MockResponse (com.google.mockwebserver.MockResponse)1 MockWebServer (com.google.mockwebserver.MockWebServer)1 HystrixInvokable (com.netflix.hystrix.HystrixInvokable)1 HystrixCollapser (com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)1