@Retry和@Recover可以在使用RestTemplate中的错误处理器时使用吗?

huangapple 未分类评论72阅读模式
英文:

Can @Retry and @Recover be used when using error handler in RestTemplate?

问题

使用Rest Template调用REST API。为了处理异常,我使用了自定义的ErrorHandler。

我还使用了@Retry和@Recover。当首次从URL出现ConnectException时,应该在第二个URL上进行调用。然而,尽管我已经定义了一个recover方法,但在经过3次尝试后,仍然抛出ExhaustedRetry 'could not find Recover method'异常。

这是因为我使用了一个ErrorHandler,而没有显式地抛出异常吗?

以下是我的代码框架 -

  1. @Component
  2. public class TestCall {
  3. @Autowired
  4. private RestTemplate restTemplate;
  5. private boolean flag = false;
  6. @Retryable(value = {ConnectException.class}, maxAttempts = 3, backoff = @Backoff(delay = 96, maxDelay = 158, random = true))
  7. public void callAPI() {
  8. restTemplate.setErrorHandler(new RestErrorHandler());
  9. if (!flag) {
  10. // 调用第一个URL
  11. flag = !flag;
  12. restTemplate.exchange(url1, HttpMethod.POST, body, Response.class);
  13. } else {
  14. // 如果第一个URL因ConnectException失败,则重试第二个URL
  15. flag = !flag;
  16. restTemplate.exchange(url2, HttpMethod.POST, body, Response.class);
  17. }
  18. }
  19. @Recover
  20. public void recover(ConnectException exception) {
  21. System.out.println("在recover方法中");
  22. }}
  23. 错误处理程序 -
  24. ```java
  25. public class RestErrorHandler implements ResponseErrorHandler {
  26. @Override
  27. public boolean hasError(ClientHttpResponse response) throws IOException {
  28. return false;
  29. }
  30. @Override
  31. public void handleError(ClientHttpResponse response) throws IOException {
  32. // 在这里记录错误
  33. }
  34. }

在重试了3次后,如果第4次抛出异常,recover方法不会被调用。

英文:

I am using Rest Template to call a rest API. To handle the exceptions, I am using a custom ErrorHandler.

I have also used @Retry and @Recover. When at first there is a ConnectException from the URL, the call should be made on the second URL. However after 3 attempts, the ExhaustedRetry 'could not find Recover method' exception is being thrown, even though I have defined a recover method.

Is it because I am using an ErroHandler and not explicitly throwing the exception?

Below is a skeleton of my code -

  1. @Component
  2. public class TestCall {
  3. @Autowired
  4. private RestTemplate restTemplate;
  5. private boolean flag = false;
  6. @Retryable(value = {ConnectException.class}, maxAttempts = 3, backoff = @Backoff(delay = 96, maxDelay = 158, random = true))
  7. public void callAPI() {
  8. restTemplate.setErrorHandler(new RestErrorHandler());
  9. if (!flag) {
  10. // calling first URL
  11. flag = !flag;
  12. restTemplate.exchange(url1, HttpMethod.POST, body, Response.class);
  13. } else {
  14. // retrying with 2nd url if 1st url fails with ConnectException
  15. flag = !flag;
  16. restTemplate.exchange(url2, HttpMethod.POST, body, Response.class);
  17. }
  18. }
  19. @Recover
  20. public void recover(ConnectException exception) {
  21. System.out.println("In recover method");
  22. }}

The error handler -

  1. public class RestErrorHandler implements ResponseErrorHandler {
  2. @Override
  3. public boolean hasError(ClientHttpResponse response) throws IOException {
  4. return false;
  5. }
  6. @Override
  7. public void handleError(ClientHttpResponse response) throws IOException {
  8. //logging the error here
  9. }
  10. }

After retrying 3 times, if the exception is thrown the 4th team, the recover method is not being called.

huangapple
  • 本文由 发表于 2020年8月15日 00:36:42
  • 转载请务必保留本文链接:https://java.coder-hub.com/63416750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定