Trying to exclude an exception using @Retryable - causes ExhaustedRetryException to be thrown

╄→гoц情女王★ 提交于 2019-12-05 16:01:03

Your include/exclude syntax looks bad - that won't even compile.

I just wrote a quick test and it works exactly as expected if you have zero @Recover methods...

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;

@SpringBootApplication
@EnableRetry
public class So38601998Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(So38601998Application.class, args);
        Foo bean = context.getBean(Foo.class);
        try {
            bean.out("foo");
        }
        catch (Exception e) {
            System.out.println(e);
        }
        try {
            bean.out("bar");
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }


    @Bean
    public Foo foo() {
        return new Foo();
    }

    public static class Foo {

        @Retryable(include = IllegalArgumentException.class, exclude = IllegalStateException.class,
                maxAttempts = 5)
        public void out(String foo) {
            System.out.println(foo);
            if (foo.equals("foo")) {
                throw new IllegalArgumentException();
            }
            else {
                throw new IllegalStateException();
            }
        }

    }

}

Result:

foo
foo
foo
foo
foo
java.lang.IllegalArgumentException
bar
java.lang.IllegalStateException

If you just add

@Recover
public void connectionException(IllegalArgumentException e) {
    System.out.println("Retry failure");
}

You get

foo
foo
foo
foo
foo
Retry failure
bar
org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.IllegalStateException

So you need a catch-all @Recover method...

@Recover
public void connectionException(Exception e) throws Exception {
    System.out.println("Retry failure");
    throw e;
}

Result:

foo
foo
foo
foo
foo
Retry failure
bar
Retry failure
java.lang.IllegalStateException
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!