从Throwable获取Root错误消息

时间:2011-04-04 18:50:06

标签: java exception-handling

我正在处理我正在进行的Web项目上的错误处理,我遇到了一个案例,其中我向用户显示的错误并不是特别有用。我一直用它来获取错误信息,以便显示给我的用户:

catch (Throwable t) {
    ...
    t.getMessage();
    ...
}

通常效果很好,通常会为用户提供比丑陋的堆栈跟踪更好的消息,而他们不知道该怎么做。但是,在一种情况下,Hibernate抛出异常并显示错误消息:

  

无法插入[some.class.name.Here]

这是非常无益的。错误的实际原因隐藏在堆栈跟踪中:

  

仅接受1753年1月1日至9999年12月31日之间的日期。

鉴于第一条错误消息,我不知道出了什么问题。鉴于第二,我至少知道要看看我输入的日期。为了解决这个问题,我这样做了:

catch (Throwable t) {
    ...
    ExceptionUtils.getExceptionMessageWithCauses(t);
    ...
}

...

public class ExceptionUtils
{
    public static String getExceptionMessageWithCauses(Throwable t)
    {
        if ( t.getCause() == null ) {
            return t.getMessage();
        } else {
            return t.getMessage() 
                + "; caused by: " 
                + getExceptionMessageWithCauses(t.getCause());
        }
    }
}

我首先担心的是,如果两个Throwable类相互引用,我可能会进入某种无限循环。或者,类似地,根本原因是如此之深,以至于即使显示来自Throwables的更友好的错误消息也会产生比堆栈跟踪更好的结果。所以,有两个问题:

  1. 做这样的事情是“安全的”,还是人们会想到这会在我脸上爆炸的情况?

  2. 除了逐个检查每个可能的错误情况之外,还有更好的方法来处理异常吗?

  3. 谢谢!

1 个答案:

答案 0 :(得分:2)

嗯,您通常会在网络层验证用户输入,因此您就知道错误的输入是什么。如果从hibernate或数据库驱动程序获得SQLException,通常无法自动且精美地获得真正的原因。

我们所做的是捕获可能对用户有意义的所有异常(它们通常是已检查的异常),所有其他异常(通常是RuntimeExceptions)只是用“发生内部错误”消息处理。

我们的一般例外是ValidationException,它由我们的验证框架抛出,并包含生成一条好消息所需的所有数据(通常是可翻译的)。

编辑:

有时可能需要遍历原因以获得您显示的异常。例如,我们有持久层抛出的异常,但它们通过EJB层传递,因此包含在EJBExceptions中。因此,我们遍历原因,直到找到一个异常并显示一条好消息或者显示“内部错误”一个。

请注意,通常用户不应该遇到默认的错误消息,因为大多数人不知道这意味着什么(“嗯,什么是NullPointerException ????”)

相关问题