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

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

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,而没有显式地抛出异常吗?

以下是我的代码框架 -

@Component
public class TestCall {

@Autowired
private RestTemplate restTemplate;

private boolean flag = false;

@Retryable(value = {ConnectException.class}, maxAttempts = 3, backoff = @Backoff(delay = 96, maxDelay = 158, random = true))
public void callAPI() {

    restTemplate.setErrorHandler(new RestErrorHandler());

    if (!flag) {
        // 调用第一个URL
        flag = !flag;
        restTemplate.exchange(url1, HttpMethod.POST, body, Response.class);
    } else {
        // 如果第一个URL因ConnectException失败,则重试第二个URL
        flag = !flag;
        restTemplate.exchange(url2, HttpMethod.POST, body, Response.class);
    }
    
}

@Recover
public void recover(ConnectException exception) {
    System.out.println("在recover方法中");
}}

错误处理程序 -

```java
public class RestErrorHandler implements ResponseErrorHandler {

@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
    return false;
}

@Override
public void handleError(ClientHttpResponse response) throws IOException {
    // 在这里记录错误
}
}

在重试了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 -

@Component
public class TestCall {

@Autowired
private RestTemplate restTemplate;

private boolean flag = false;

@Retryable(value = {ConnectException.class}, maxAttempts = 3, backoff = @Backoff(delay = 96, maxDelay = 158, random = true))
public void callAPI() {
    
    restTemplate.setErrorHandler(new RestErrorHandler());

    if (!flag) {
        // calling first URL
        flag = !flag;
        restTemplate.exchange(url1, HttpMethod.POST, body, Response.class);
    } else {
        // retrying with 2nd url if 1st url fails with ConnectException
        flag = !flag;
        restTemplate.exchange(url2, HttpMethod.POST, body, Response.class);
    }
    
}

@Recover
public void recover(ConnectException exception) {
    System.out.println("In recover method");
}}

The error handler -

public class RestErrorHandler implements ResponseErrorHandler {

@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
    return false;
}

@Override
public void handleError(ClientHttpResponse response) throws IOException {
    //logging the error here
}
}

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:

确定