2009-05-19 10 views
4

ので、私は正しくのprintStackTraceは

ServletExceptionがキャッチし、情報のほとんどが失われているのprintStackTraceを呼び出す(私たちは、JSFのミックス/平野サーブレットを使用しているため)サーブレット例外をキャッチするためにフィルタを使用しています。

「真」のルート例外は、「面白い」という表現

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

これは明らかにそれを行うための方法ではありません背後に隠されているように見えます。

は、そのような例外の「完全な」情報を簡単に印刷する方法です。 例外がこのようにラップされている理由を誰かが説明できますか?

答えて

6

はcommons-からExceptionUtilsクラスを見てみましょう:あなたは、その根本原因をのIteratorすることができますキャッチされた例外の一番下の(および他のすべて)の例外(複数可)を取得する

ラング。これには、一連の例外をすべて印刷するための便利なメソッドがいくつか含まれています。

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

このアプローチの問題:高いレベルの例外(そのメッセージ)についての情報のトンが失われる。ここ はServletExceptionsのためのすべての拠点をカバーし、我々が使用している再帰的な方法です。 –

+0

私は彼が例外の連鎖を削除したいとは思わない - ちょうどそれを知的に記録する –

+0

正義のために投票する。それは解決策を提供しませんが、これは例外の入れ子を説明しました。 –

3

私はExceptionUtilsを見た後、これが問題を解決しました!

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

これは、関連するすべての情報とともに完全なスタックトレースを出力します。

+0

ハァッか。 Throwable.printStackTrace()も同様です。 –

+1

Throwable.printStackTrace()は、Throwable.getCause()チェーンの後にのみあります。例外の根本的な原因を格納するために異なるメソッド名を使用する(Java 1.4より前にこれを行う非標準的な方法のために)、多くの例外的な例外(SQLExceptionなど)があります。ExceptionUtilsは、getNextException、getTargetException、getRootCauseなどのメソッドに従います(完全なリストについてはクラスを参照してください) – David

0

ServletExceptionの例外チェーンは扱いにくいです。使用中のWebサーバー実装およびWeb開発フレームワークによっては、実行時にチェーンが原因および/またはrootCauseを使用する可能性があります。このlinkは非常によく説明しています。事を複雑にするために、私は、例外が例外自体を指し示す例外を見ました。

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; 
    } 
}