【问题标题】:What is a good way to wrap this exception?包装此异常的好方法是什么?
【发布时间】:2025-12-05 05:20:07
【问题描述】:

我正在为我的 springboot 应用程序实现一个 HealthIndicator,它会 ping Jenkins 实例以检查它们是否启动。我通过 ping ${JENKINS_URL}/login 来做到这一点。如果它出现了,我会收到 200 个响应。如果它没有启动,我会得到一个非常丑陋的堆栈跟踪,如下所示:

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]

我的驱动程序代码如下所示(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";
    }

我宁愿捕获一个特定的异常,但如果 ping 一个关闭的 Jenkins 实例会产生一个 InvalidMediaTypeException,它看起来有点令人困惑(即我希望像 RestClientException 这样的东西)。什么是捕获/处理此异常的好方法?我应该改用RuntimeException 吗?

【问题讨论】:

    标签: java spring-boot exception spring-boot-actuator


    【解决方案1】:

    好吧,如果知道从该调用返回的预期异常是 InvalidMediaTypeException ,那么您只需创建一个 RestClientException 并将其重新抛出给调用 pingJenkins 的调用者.然后,任何使用您的 API 的人都将期待 RestClientException。由于这是 Spring Boot,您甚至可以使用全局异常处理程序 enter link description here 来捕获该异常,而无需您这样做。

    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";
    }
    

    【讨论】:

    • 我明白了。 callingMethod() 不必处理 RestClientException - 我只是想以一种有意义的方式处理该异常,在我的测试中我只有遇到InvalidMediaTypeException,我不知道如果我应该期待任何其他类型的异常
    • 我真的很惊讶您收到该错误,因为对 getForEntity 的调用返回的不是 RestClientException。查看 Javadoc:docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
    • 我知道,对!我也期待一个 RestClientException!
    最近更新 更多