英文:
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) {
//您的代码
}
这将处理IOException
和RestClientException
。尽管这是一个简短且易于阅读的解决方案,但如果您可能需要以不同的方式捕获其他异常,那么您可能会考虑不这样做。但在许多情况下,这可能会对您有所帮助。最终决定是否采用这种方式取决于您。
捕获多个异常
代码
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论