@Recover не работает для пользовательского исключения

#java #spring #spring-retry

Вопрос:

Следующая повторная попытка работает нормально. Метод восстановления был вызван после 3 неудачных попыток

 @Retryable(value = MyException.class) public String getSomething(String performanceId) {  String s = "test";  ...  throw new MyException("test", new RuntimeException());  ...  return s;  }  @Recover public String recover(MyException exception, String performanceId) {  log.info("In recover method!!!!!!!!!!!!!!!!!!");  return "test"; }  

Но следующий метод восстановления не будет вызван, когда я изменил тип возвращаемого значения. Не могли бы вы, пожалуйста, рассказать, почему и как это исправить? Большое спасибо!

 @Retryable(value = MyException.class) public MyOwnType getSomething(String performanceId) {  MyOwnType s = new MyOwnType();  ...  throw new MyException("test", new RuntimeException());  ...  return s;  }  @Recover public MyOwnType recover(MyException exception, String performanceId) {  log.info("In recover method!!!!!!!!!!!!!!!!!!");  return new MyOwnType(); }  

 public class MyOwnType implements Serializable { ... }  

Редактировать: Я забыл упомянуть, что я также создаю пользовательское исключение

 public class MyException extends RuntimeException {   private static final long serialVersionUID = 1L;   public MyException(String message, Throwable cause) {  super(message, cause);  }  }  

Ответ №1:

Это прекрасно работает для меня; вы уверены @EnableRetry , что сделали это ?

 @SpringBootApplication @EnableRetry public class So69916559Application {   public static void main(String[] args) {  SpringApplication.run(So69916559Application.class, args);  }    @Bean  ApplicationRunner runner(Test test) {  return args -gt; {  System.out.println(test.getSomething("foo"));  };  }  }  @Component class Test {   private static final Logger log = LoggerFactory.getLogger(Test.class);   @Retryable(value = RuntimeException.class)  public MyOwnType getSomething(String performanceId) {  MyOwnType s = new MyOwnType();  log.info("here");  throw new RuntimeException();  }   @Recover  public MyOwnType recover(RuntimeException exception, String performanceId) {  log.info("In recover method!!!!!!!!!!!!!!!!!!");  return new MyOwnType();  }  }  class MyOwnType implements Serializable {  }  

Результат

 here here here In recover method!!!!!!!!!!!!!!!!!! com.example.demo.MyOwnType@3f725306  

Комментарии:

1. Спасибо за ваш ответ! Да, у меня есть все необходимые аннотации. В противном случае первый случай не сработал бы. Я забыл упомянуть, что я создаю пользовательское исключение, которое может охватывать различные типы исключений. Я подозреваю, что это может быть причиной?

Ответ №2:

Проблема устранена путем изменения метода восстановления на

 @Recover public MyOwnType recover(RuntimeException exception, String performanceId) {  log.info("In recover method!!!!!!!!!!!!!!!!!!");  return new MyOwnType(); }  

Даже несмотря на то, что MyException расширяет исключение RuntimeException. Метод восстановления не будет вызван, если он ожидает исключения MyException. Не знаю, почему