Java Try Catch如何去掉外层A1异常直接抛出A9异常且无Caused by块
问题结论
你调整后的代码不能实现需求,首先存在编译错误:两个同级catch块都捕获Exception类型,属于重复捕获,不符合Java语法要求,代码无法正常运行。即使忽略编译问题,异常抛出后依然会被第二个catch块捕获,二次包装为新的AException,还是会生成外层异常和Caused by结构。
原代码问题根源
你在try块中主动抛出A9类型的AException后,会被后续的catch (Exception e)捕获,此时你新创建了一个AException并把原异常作为构造参数传入,相当于给原A9异常套了一层外层的A1异常,原异常就被放到了Caused by块中,才会出现你现在看到的异常格式。
正确修改方案
核心逻辑是:避免对主动抛出的A9异常二次包装,抛出新异常时不要传入原异常作为构造参数,就不会生成Caused by块,推荐两种实现方式:
方案1:用try-with-resources自动管理连接,分类捕获异常(推荐)
public Sample Method (Input input) throws AException { // try-with-resources会自动关闭连接,无需手写finally try (Connection con = getSQLConnection()){ //do something if(x==null){ throw new AException(A9ErrorMessages.A9_ERROR_FROM_TABLE, new String [] { "ColName", "TableName"}); } } // 只捕获系统级异常,不捕获主动抛出的AException catch (SQLException e){ logger().error(e); // 转A9抛出时不要传入原异常e作为参数,避免生成cause链 throw new AException(A9ErrorMessages.A9_ERROR_FROM_TABLE, new String [] { "ColName", "TableName"}); } }
方案2:必须捕获所有异常时,增加类型判断避免二次包装
public Sample Method (Input input) throws AException { Connection con = null; try{ con = getSQLConnection(); //do something if(x==null){ throw new AException(A9ErrorMessages.A9_ERROR_FROM_TABLE, new String [] { "ColName", "TableName"}); } } catch (Exception e){ logger().error(e); // 如果已经是目标A9异常,直接抛出不要二次包装 if (e instanceof AException && ((AException) e).getErrorCode().equals(A9ErrorMessages.A9_ERROR_FROM_TABLE.getCode())) { throw e; } // 其他异常转A9抛出,不传入原异常参数 throw new AException(A9ErrorMessages.A9_ERROR_FROM_TABLE, new String [] { "ColName", "TableName"}); } finally{ if(con!=null){ try{ con.close(); } catch(Exception e){ // 连接关闭异常只打日志,不要往外抛避免覆盖业务异常 logger().error("连接关闭失败", e); } } } }
调整后抛出的异常不会有外层包装,也不会携带异常根因链,完全符合你要求的输出格式。
内容的提问来源于stack exchange,提问作者dcd
相关产品推荐
相关产品推荐

