Java RestTemplate:从ResponseErrorHandler引发的自定义异常未传播到调用方

Java RestTemplate:从ResponseErrorHandler引发的自定义异常未传播到调用方,java,spring,exception,exception-handling,resttemplate,Java,Spring,Exception,Exception Handling,Resttemplate,我正在开发一个API。按照其他干净的编程准则,我不想用try/catch块把代码弄得乱七八糟。然而,我面临一个挑战:ResponseErrorHandler抛出的自定义异常没有传播到调用方;相反,调用方接收的是ResourceAccessException 这是我的API代码(为了简洁起见,省略了不相关的部分)。注意,我不是在try块中围绕restemplate.delete()调用-这是有意的: restTemplate.setErrorHandler(ecmResponseErrorHand

我正在开发一个API。按照其他干净的编程准则,我不想用try/catch块把代码弄得乱七八糟。然而,我面临一个挑战:ResponseErrorHandler抛出的自定义异常没有传播到调用方;相反,调用方接收的是ResourceAccessException

这是我的API代码(为了简洁起见,省略了不相关的部分)。注意,我不是在try块中围绕restemplate.delete()调用-这是有意的:

restTemplate.setErrorHandler(ecmResponseErrorHandler);
restTemplate.delete(serviceUrl, params);
我的ecmResponseErrorHandler代码(为了简洁起见,省略了不相关的部分):

我的ECMEException是(为了简洁起见,省略了不相关的部分):

现在,我的JUnit测试用例接收的不是ECMEException,而是ResourceAccessException:

java.lang.Exception: Unexpected exception, expected<com.db.dbbpm.ecmfacade.exception.ECMException> but was<org.springframework.web.client.ResourceAccessException>

为什么ResponseErrorHandler抛出的ECMEException不会一直传播到调用方?如何实现它?

让ECMEException扩展RuntimeException(而不是IOException)解决了这个问题。现在我的代码更干净了

public class ECMException extends RuntimeException {

    public ECMException() {
        super();
    }
    //etc.
}

经过几天的考虑,我决定不抛出任何自定义异常。它不会为了创建自定义异常而添加任何值;相反,我抛出了从
restemplate
调用收到的异常;e、 g.
HttpClientErrorException
。我认为没有必要创建自定义异常,因为我的API的调用方必须知道新的自定义异常,而像
HttpClientErrorException
这样的异常更为“已知”和有意义。我处于同一启动状态,我想将错误包装到特定于rest端点的自定义异常层次结构中。我认为在客户端代码中处理确切的异常并忘记响应状态是个好主意。因为ResponseErrorHandler只处理带有响应的调用,如果无法连接,则从其他spring代码中抛出ResourceAccessException,并且它根本不使用ResponseErrorHandler。顺便说一下,干净的代码还说不要使用编码名称。。。ECMEException到底是什么?:)@DanielHári:在我的领域,你听到ECM的次数甚至比听到HTTP的次数还要多:我同意,如果将
ECM
替换为
my
,问题和答案的可读性会更高。
java.lang.Exception: Unexpected exception, expected<com.db.dbbpm.ecmfacade.exception.ECMException> but was<org.springframework.web.client.ResourceAccessException>
restTemplate.setErrorHandler(ecmResponseErrorHandler);
try {
    restTemplate.delete(serviceUrl, params);
} catch () {
    throw new ECMException();
}
public class ECMException extends RuntimeException {

    public ECMException() {
        super();
    }
    //etc.
}