如何在客户端处理RestTemplate的异常?

huangapple go评论65阅读模式
英文:

How to handle RestTemplate Exceptions in a client?

问题

I have a springboot application which invokes a Client Library I've written, to make REST calls to a third-party service.

I want to be able to catch any/all exceptions which may come from this client library and map them to my own custom exception, which I can catch in my application.

Within the Client Library, I have a RestTemplate bean, and I've bound an ErrorHandler to it, like so:

public class CustomRestTemplateErrorHandler implements ResponseErrorHandler {

}

I use the typical methods of 'hasError' and 'handleError'. If I return an HTTP 400 with some expected error response body, I can catch this error and map it to my exception, as shown here:

@Override
public void handleError(ClientHttpResponse response) {
    try {
        if (!response.getStatusCode().is2xxSuccessful()) {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(response.getBody()));
            String httpBodyResponse = reader.lines()
                    .collect(Collectors.joining(""));

            ObjectMapper mapper = new ObjectMapper();
            ExpectedErrorResponse errorResponse = mapper.readValue(httpBodyResponse, ExpectedErrorResponse.class);
            throw new CustomException(response.getStatusCode(), errorResponse);
        }
    } catch (IOException ioException) {
        throw new CustomException(ioException.getMessage(), ioException.getCause());
    }
}

Let's say I run this test, and the downstream server isn't running. I'll get the following Exception, which isn't caught by my error handler:

Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://127.0.0.1:8082/": Connect to 127.0.0.1:8082 [/127.0.0.1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:8082 [/127.0.0.1] failed: Connection refused: connect

How do I catch both the expected type of error response and a RestClientException within the ResponseErrorHandler?

Thanks

英文:

I have a springboot application which invokes a Client Library I've written, to make REST calls to a third party service.

I want to be able to catch any/all exceptions which may come from this client library, and map them to my own custom exception, which I can catch in my application.

Within the Client Library, I have a RestTemplate bean, and I've bound a ErrorHandler to it, like so:

public class CustomRestTemplateErrorHandler implements ResponseErrorHandler {

}

I use the typical methods of 'hasError' and 'handleError'. If I return a HTTP400 with some expected error response body, I can catch this error and map it to my exception, as shown here:

@Override
    public void handleError(ClientHttpResponse response) {
        try {
            if (!response.getStatusCode().is2xxSuccessful()) {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(response.getBody()));
                String httpBodyResponse = reader.lines()
                        .collect(Collectors.joining(""));

                ObjectMapper mapper = new ObjectMapper();
                ExpectedErrorResponse errorResponse = mapper.readValue(httpBodyResponse, ExpectedErrorResponse.class);
                throw new CustomException(response.getStatusCode(), errorResponse);
            }
        } catch (IOException ioException) {
            throw new CustomException(ioException.getMessage(), ioException.getCause());
        }
    }

Lets say I run this test, and the downstream server isn't running. I'll get the following Exception, which isn't caught by my error handler: Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://127.0.0.1:8082/": Connect to 127.0.0.1:8082 [/127.0.0.1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to 127.0.0.1:8082 [/127.0.0.1] failed: Connection refused: connect

How do I catch both the expected type of error response, and a RestClientException, within the ResponseErrorHandler?

Thanks

答案1

得分: 0

问题描述

ResourceAccessException 是一个不继承自 IOException 的异常 class,所以在这种特定情况下,您的 catch 将不会被执行。因此,您有几个选项:

捕获异常

代码:

catch (Exception exception) {
    //您的代码
}

这将处理IOExceptionRestClientException。尽管这是一个简短且易于阅读的解决方案,但如果您可能需要以不同的方式捕获其他异常,那么您可能会考虑不这样做。但在许多情况下,这可能会对您有所帮助。最终决定是否采用这种方式取决于您。

捕获多个异常

代码

catch (IOException ioException) {
    // 您的代码
} catch (RestClientException restClientException) {
    // 您的代码
}

如果第一个建议不起作用,这正是您想要的,因此这是一个有用的解决方案。

在同一个块中捕获多个异常类型

代码

catch (IOException | RestClientException myException) {
    // 您的代码
}

这是对您想要处理的根异常类型进行白名单处理的一种简洁方式来解决问题。

英文:

Problem statement

ResourceAccessException is an exception class which is not inherited from IOException, so your catch will not be entered in this specific case. So, you have several options:

Catch Exception

Code:

catch (Exception exception) {
    //your code
}

this would handle both IOException and RestClientException. Even though this is a short and easy-to-read solution, if you may have other exceptions to catch in a different manner, then you may want to decide against it. But in many cases this could help you. Ultimately it is you who needs to decide whether this is the way to go.

Catch multiple exceptions

Code

catch (IOException ioException) {
    // Your code
} catch (RestClientException restClientException) {
    // Your code
}

This is precisely doing what you want, so it is a useful solution if the first suggestion does not help.

Catch multiple exception types in the same block

Code

catch (IOException | RestClientException myException) {
    // Your code
}

This is whitelisting the root exception types you want to handle and it's a neat way to approach the problem.

huangapple
  • 本文由 发表于 2023年4月13日 18:50:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76004543.html
匿名

发表评论

匿名网友

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

确定