【问题标题】:Using specific try catch, error overrides使用特定的 try catch,错误覆盖
【发布时间】:2014-10-15 19:39:30
【问题描述】:

这是我的例外:

public class MyException extends Exception {

private String errorCode="Unknown_Exception";

public MyException(String message, String errorCode){
    super(message);
    this.errorCode=errorCode;
}

public String getErrorCode(){
    return this.errorCode;
}
}

现在想象下一个场景,代码太长,无法粘贴到这里:
1 我在 Presentation 包中获得了一个用 Swing 制作的 Presentation 类
2 在包计算中,我使用收到的数据库字段中的少量数字进行了简单的操作
3 在包连接中我得到了数据库连接

麻烦来了:
- 在表示层中,我捕获所有错误,如下所示:

    try {
        //here is a method called updateCombo() wich throws: 
        //throw new MyException(e.getMessage(),"ERROR_UPDATING_COMBO_BOX");
    } catch (MyException ex) {
        try {
            //Here we process error code, if error is not defined, uses default errors.
            processCode(ex);
        } catch (MyException ex1) {
            Logger.getLogger(Presentacion.class.getName()).log(Level.SEVERE, null, ex1);
        }
    }

processCode 是一个包含案例的简单列表,如下所示:

private void processCode(MyException e) throws MyException {
    switch (e.getErrorCode()) {
        case "ERROR_UPDATING_COMBO_BOX":
            lblErrorText.setText("Error updating combo.");
            throw e;
        case "ERROR_SELECTING_PRIMARY_KEY":
            lblErrorText.setText("Error selecting PK");
            throw e;
        case "ERROR_OPENING_CONNECTION":
            lblErrorText.setText("Error opening connection.");
            throw e;
        default:
            lblErrorText.setText("Excepcion not defined: "+ e.getMessage());
            e.printStackTrace();
    }

这是场景,在第三个包中连接失败并导致:

throw new MyException(e.getMessage(),"ERROR_OPENING_CONNECTION");

正如我所说,错误通过方法头中的 throws 子句被抛出到上层,这是第二个包。
由于连接失败,第二个包还会向 Presentation 抛出一个新异常:

throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");

表示方法也会抛出此异常,因为第 2 层失败:

throw new MyException(e.getMessage(),"ERROR_UPDATING_COMBO_BOX");

主要问题:

使用调试,我发现程序做了它必须做的事情。它到达连接层并成功完成:

throw new MyException(e.getMessage(),"ERROR_OPENING_CONNECTION");

但是,在第 2 层计算中,如果连接失败,则会引发新的异常:

throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");

这就是问题所在:

throw new

抛出新异常会用 ERROR_SELECTING_PRIMARY_KEY 覆盖 ERROR_OPENING_CONNECTION。当它由于“throw new”而进入演示文稿时,会用 ERROR_UPDATING_COMBO_BOX 覆盖 ERROR_SELECTING_PRIMARY_KEY,从而导致屏幕上显示的最终错误:

lblErrorText.setText("Error updating combo.");

有什么方法可以在捕获第一个错误而不被下一个错误覆盖后返回到演示文稿?
也许我误解了这个概念,但我想捕捉所有可能的错误,因为:
- 如果连接正常但第 2 层中的方法失败,则应抛出 ERROR_SELECTING_PRIMARY_KEY。 - 如果第 2 层(计算)没有问题,但演示中存在错误,则应导致 ERROR_UPDATING_COMBO_BOX。

【问题讨论】:

    标签: java


    【解决方案1】:

    您可以使用e.getCause(),它将返回Throwable,并检查此原因是否属于MyException。如果是这样,您可以再次递归检查e.getCause(),直到您获得堆栈跟踪中最深的错误代码并执行此异常的验证。

    这是一个例子:

    public MyException getDeepestException(MyException e) {
        Throwable t = e.getCause();
        if (t instanceof MyException) {
            return getDeepestException((MyException)t);
        }
        return e;
    }
    

    正如@RealSkeptic 所指出的,为了使用这种方法,您需要在自定义异常中添加一个额外的构造函数:

    public MyException(String message, Throwable cause, String errorCode){
        super(message, cause);
        this.errorCode = errorCode;
    }
    

    在抛出异常时,调用正确的构造函数:

    try {
        //...
    } catch (SomeException e) {
        throw new MyException(<a proper message should be here>, e, "ERROR_SELECTING_PRIMARY_KEY");
    }
    

    【讨论】:

    • 好的,这进入了 MyException 类,但我如何在演示中使用它?
    • 这将是您要在 processCode 方法中使用的确切例外。
    • 请注意,要使其有用,必须更改 MyException 的构造函数以接受原因,并且必须调用适当的 super() 来设置该原因。
    • @RealSkeptic 你能把它贴在你的评论里吗? :P
    • @LuiggiMendoza 完成但还没有工作,xD 我必须更改 MyException 类中的任何内容吗?
    【解决方案2】:

    如果我理解正确,如果一个包捕获的异常恰好是 MyException,则您希望传递原始 MyException,否则(如果异常是其他类型的 Exception)您想创建一个新的我的异常。

    在这种情况下,您应该有两个 catch 子句。

    try {
        // Whatever you do in the try clause
    } catch ( MyException myEx ) {
        throw myEx;
    } catch ( Exception e ) {
        throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多