2009-05-19 54 views
4

所以我使用的是過濾器捕捉servlet異常(因爲我們使用JSF的混合/純的servlet)捕捉的ServletException和調用的printStackTrace大部分的信息丟失時servlet異常的正確的printStackTrace

「真正」的根異常,似乎背後的「有趣」表達

((ServletException) e.getRootCause().getCause()).getRootCause().getCause().getCause().getCause() 

要隱藏這顯然不這樣做的方式。

是打印此類異常「完整」信息的簡單方法。 有人可以解釋爲什麼這個異常是這樣包裹的?

回答

6

看看從commons-的ExceptionUtils類郎。它包含幾個有用的方法來打印整個例外鏈。

1

這就是所謂的exception chaining。通過在一個不同的異常中包裝一個異常,你可以讓異常冒出堆棧,而不讓你的主應用程序類擔心一些低級異常。

例子:

public void doStuff() throws StuffException { 
    try { 
     doDatabaseStuff(); 
    } catch (DatabaseException de1) { 
     throw new StuffException("Could not do stuff in the database.", de1); 
    } 
} 

這樣,你的應用程序只需要處理StuffException但它可以得到一個底層DatabaseException如果真的需要。

要得到一個異常的最底部(和所有其他)異常()你發現你可以在迭代器其根源:

... 
} catch (SomeException se1) { 
    Throwable t = se1; 
    logger.log(Level.WARNING, "Top exception", se1); 
    while (t.getCause() != null) { 
     t = t.getCause(); 
     logger.log(Level.WARNING, "Nested exception", t); 
    } 
    // now t contains the root cause 
} 
+0

這種方法的問題:一噸約更高級別的異常(其消息)丟失的信息。 – 2009-05-19 14:29:22

+0

我不認爲他想要除去例外鏈 - 只需將其智能登錄 – 2009-05-19 14:38:29

3

我看了一下ExceptionUtils後,解決了這個問題!

final StringWriter stacktrace = new StringWriter(); 
    ExceptionUtils.printRootCauseStackTrace(throwable,new PrintWriter(stacktrace)); 
    msg.append(stacktrace.getBuffer()); 

這會打印出每一條相關信息的完整堆棧跟蹤。

0

異常鏈接ServletException是棘手的。根據所使用的Web服務器實現和Web開發框架,在運行時,鏈可能使用cause和/或rootCause。這link解釋得很好。使事情複雜化,我看到異常本身指向異常的例外。 這裏,我們使用的是涵蓋了所有ServletExceptions基地遞歸方法:

public static Throwable getDeepCause(Throwable ex) { 
    if (ex == null) { 
     return ex; 
    } 
    Throwable cause; 
    if (ex instanceof ServletException) { 
     cause = ((ServletException) ex).getRootCause(); 
     if (cause == null) { 
      cause = ex.getCause(); 
     } 
    } else { 
     cause = ex.getCause(); 
    } 
    if (cause != null && cause != ex) { 
     return getDeepCause(cause); 
    } else { 
     // stop condition - reached the end of the exception chain 
     return ex; 
    } 
}