Get failure exception in @HystrixCommand fallback method

后端 未结 5 1291
-上瘾入骨i
-上瘾入骨i 2020-12-28 08:21

Is there a way to get the reason a HystrixCommand failed when using the @HystrixCommand annotation within a Spring Boot application? It looks like

相关标签:
5条回答
  • 2020-12-28 08:53

    I couldn't find a way to obtain the exception with the annotations, but i found HystrixPlugins , with that you can register a HystrixCommandExecutionHook and you can get the exact exception in that like this :

    HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixCommandExecutionHook() {
                @Override
                public <T> void onFallbackStart(final HystrixInvokable<T> commandInstance) {
    
                }
            });
    

    The command instance is a GenericCommand.

    0 讨论(0)
  • 2020-12-28 08:55

    Simply add a Throwable parameter to the fallback method and it will receive the exception which the original command produced.

    From https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica

        @HystrixCommand(fallbackMethod = "fallback1")
        User getUserById(String id) {
            throw new RuntimeException("getUserById command failed");
        }
    
        @HystrixCommand(fallbackMethod = "fallback2")
        User fallback1(String id, Throwable e) {
            assert "getUserById command failed".equals(e.getMessage());
            throw new RuntimeException("fallback1 failed");
        }
    
    0 讨论(0)
  • 2020-12-28 08:59

    Most of the time just using getFailedExecutionException().getMessage() gave me null values.

       Exception errorFromThrowable = getExceptionFromThrowable(getExecutionException());
       String errMessage = (errorFromThrowable != null) ? errorFromThrowable.getMessage()
    

    this gives me better results all the time.

    0 讨论(0)
  • 2020-12-28 09:07

    I haven't found a way to get the exception with Annotations either, but creating my own Command worked for me like so:

    public static class DemoCommand extends HystrixCommand<String> {
    
        protected DemoCommand() {
            super(HystrixCommandGroupKey.Factory.asKey("Demo"));
        }
    
        @Override
        protected String run() throws Exception {
            throw new RuntimeException("failed!");
        }
    
        @Override
        protected String getFallback() {
            System.out.println("Events (so far) in Fallback: " + getExecutionEvents());
            return getFailedExecutionException().getMessage();
        }
    
    }
    

    Hopefully this helps someone else as well.

    0 讨论(0)
  • 2020-12-28 09:13

    As said in the documentation Hystrix-documentation getFallback() method will be thrown when:

    1. Whenever a command execution fails: when an exception is thrown by construct() or run()
    2. When the command is short-circuited because the circuit is open
    3. When the command’s thread pool and queue or semaphore are at capacity
    4. When the command has exceeded its timeout length.

    So you can easily get what raised your fallback method called by assigning the the execution exception to a Throwable object.

    Assuming your HystrixCommand returns a String

    public class ExampleTask extends HystrixCommand<String> {
       //Your class body
    }
    

    do as follows:

    @Override
        protected ErrorCodes getFallback() {
            Throwable t = getExecutionException();
            if (circuitBreaker.isOpen()) {
                // Log or something
            } else if (t instanceof RejectedExecutionException) {
                // Log and get the threadpool name, could be useful
            } else {
                // Maybe something else happened
            }
            return "A default String"; // Avoid using any HTTP request or ypu will need to wrap it also in HystrixCommand
        }
    

    More info here

    0 讨论(0)
提交回复
热议问题