什么是一个良好的方式来捕获这个异常?

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

What is a good way to wrap this exception?

问题

我正在为我的Spring Boot应用实现一个HealthIndicator,用于检查Jenkins的实例是否处于运行状态。我通过对${JENKINS_URL}/login发起请求来实现这一点。如果它处于运行状态,我会收到一个200的响应。如果它没有运行,我会得到一个类似这样的非常糟糕的堆栈跟踪:

org.springframework.http.InvalidMediaTypeException: 无效的媒体类型“html”:不包含“/”
	at org.springframework.http.MediaType.parseMediaType(MediaType.java:574) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.http.HttpHeaders.getContentType(HttpHeaders.java:966) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.getCharset(DefaultResponseErrorHandler.java:224) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:165) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:112) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:785) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:743) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:677) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:345) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at com.path.to.package.JenkinsCache.pingJenkins(JenkinsCache.java:60) [classes/:na]

我的驱动代码如下(在JenkinsCache中):

private String pingJenkins(String jenkinsEndpoint) {
     RestTemplate restTemplate = new RestTemplate();
     try{
            restTemplate.getForEntity(jenkinsEndpoint + "/login", String.class);
            return "OK";
        } catch (Exception e) {
            log.error("在 ping 时发生错误:" + jenkinsEndpoint, e);
        }
        return "DOWN";
    }

我更希望捕获一个特定的异常,但是如果对一个已经关闭的Jenkins实例进行ping操作会产生一个InvalidMediaTypeException,这段代码看起来有点混乱(我期望看到类似于RestClientException等的异常)。有什么好的方法来捕获/处理这个异常吗?我应该捕获一个RuntimeException吗?

英文:

I am implementing a HealthIndicator for my springboot application which pings instances of Jenkins to check if they're up. I do this by pinging the ${JENKINS_URL}/login. If it's up I get a 200 response. If it's not up, I get a very ugly stack trace like this:

org.springframework.http.InvalidMediaTypeException: Invalid mime type "html": does not contain '/'
	at org.springframework.http.MediaType.parseMediaType(MediaType.java:574) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.http.HttpHeaders.getContentType(HttpHeaders.java:966) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.getCharset(DefaultResponseErrorHandler.java:224) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:165) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:112) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:785) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:743) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:677) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:345) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
	at com.path.to.package.JenkinsCache.pingJenkins(JenkinsCache.java:60) [classes/:na]

My driver code looks like this (in JenkinsCache):

private String pingJenkins(String jenkinsEndpoint) {
     RestTemplate restTemplate = new RestTemplate();
     try{
            restTemplate.getForEntity(jenkinsEndpoint+"/login", String.class);
            return "OK";
        } catch (Exception e) {
            log.error("An error occurred while pinging: "+jenkinsEndpoint, e);
        }
        return "DOWN";
    }

I'd rather catch a specific exception but if pinging a Jenkins Instance that is down produces an InvalidMediaTypeException, it looks a little confusing bit of code (i.e. I'd expect something like a RestClientException, etc). What is a good way to catch/handle this exception? Should I catch a RuntimeException instead?

答案1

得分: 0

如果**知道从此调用返回的预期异常是 `InvalidMediaTypeException`,那么你只需创建一个 `RestClientException` 并将其重新抛出给调用 `pingJenkins` 的调用者然后无论谁使用你的 API都将期望一个 `RestClientException`。由于这是 Spring Boot你甚至可以使用一个全局异常处理程序[链接描述在这里][1]来捕获该异常而无需你自己处理

public void callingMethod() {
    try {
        pingJenkins("http://www.jenkins-endpoint.com");
    } catch (RestClientException exception) {
        log.error("无法连接到 Jenkins", exception);
    } 
}

private String pingJenkins(String jenkinsEndpoint) {
    RestTemplate restTemplate = new RestTemplate();
    try{
        restTemplate.getForEntity(jenkinsEndpoint + "/login", String.class);
        return "OK";
    } catch (InvalidMediaTypeException exception) {
        throw new RestClientException("Pinging Jenkins 失败:" + exception.getMessage());
    }

    return "DOWN";
}

[1]: https://www.baeldung.com/exception-handling-for-rest-with-spring
英文:

Well, if you know that the expected Exception that comes back from this call is the InvalidMediaTypeException , the you simply crate a RestClientException and rethrow it to the caller that calls pingJenkins. Then, whomever uses your API will expect a RestClientException. Since this is Spring Boot, you could even use a global exception handler enter link description here that will catch that exception without you needing to.

public void callingMethod() {
    try {
        pingJenkins("http://www.jenkins-endpoint.com");
    } catch (RestClientException exception) {
        log.error("Could not connect to Jenkins", exception);
    } 
}

private String pingJenkins(String jenkinsEndpoint) {
    RestTemplate restTemplate = new RestTemplate();
    try{
        restTemplate.getForEntity(jenkinsEndpoint+"/login", String.class);
        return "OK";
    } catch (InvalidMediaTypeException exception) {
        throw new RestClientException("Pinging Jenkins failed: " + exception.getMessage());
    }

    return "DOWN";
}

huangapple
  • 本文由 发表于 2020年4月7日 12:42:20
  • 转载请务必保留本文链接:https://java.coder-hub.com/61072968.html
匿名

发表评论

匿名网友

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

确定