2009-05-19 8 views
4

so verwende ich einen Filter Servlet Ausnahme zu fangen (weil wir eine Mischung aus JSF/plain Servlets verwenden)richtig print von Servlet Ausnahme

wenn die ServletException Fang- und print Aufruf der größte Teil der Informationen verloren gehen.

die „wahre“ root Ausnahme scheint hinter dem „lustigen“ Ausdruck

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

ist dies eindeutig nicht der richtige Weg, es zu tun versteckt werden.

ist eine einfache Möglichkeit, die "vollständige" Informationen einer solchen Ausnahme zu drucken. kann mir jemand erklären, warum die Ausnahme so verpackt ist?

Antwort

6

Werfen Sie einen Blick auf die ExceptionUtils Klasse von commons- lang. Es enthält mehrere nützliche Methoden zum Drucken der gesamten Kette von Ausnahmen.

1

Das heißt exception chaining. Wenn Sie eine Exception in eine andere Exception einbinden, können Sie Exceptions im Stack platzen lassen, ohne dass sich Ihre Hauptanwendungsklassen Sorgen um einige Low-Level-Exceptions machen müssen.

Beispiel:

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

Auf diese Weise nur Ihre Anwendung hat StuffException zu handhaben, aber es kann auf die darunter liegenden DatabaseException, wenn es wirklich braucht.

auf die am weitesten unten (und alle anderen) Ausnahme (n) einer Ausnahme bekommen Sie gefangen Sie seine Ursachen Iterator über können:

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

das Problem bei diesem Ansatz: eine Tonne Informationen über höhere Ebene Ausnahmen (ihre Nachrichten) verloren. –

+0

Ich glaube nicht, dass er die Kette von Ausnahmen entfernen will - loggen Sie es einfach intelligent ein –

+0

für gute Gerechtigkeit stimmend. obwohl es keine Lösung bietet, erklärte dies die Verschachtelung von Ausnahmen. –

3

nachdem ich ExceptionUtils gesehen habe, löste dies das Problem!

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

Dies druckt den vollständigen StackTrace mit jeder relevanten Information aus.

+0

Huh? Dies gilt auch für Throwable.printStackTrace(). –

+1

Throwable.printStackTrace() folgt nur der Throwable.getCause() - Kette. Es gibt eine Menge von Oddball-Ausnahmen (z. B. SQLException), die unterschiedliche Methodennamen verwenden, um die Grundursache einer Ausnahme zu speichern (aufgrund einer nicht standardmäßigen Vorgehensweise, dies vor Java 1.4 zu tun).ExceptionUtils folgt Methoden wie getNextException, getTargetException, getRootCause usw. (siehe die Klasse für die vollständige Liste) – David

0

Ausnahmeverkettung für ServletException ist schwierig. Abhängig von der verwendeten Webserver-Implementierung und dem Web-Entwicklungs-Framework kann die Kette zur Laufzeit cause und/oder rootCause verwenden. Diese link erklärt es sehr gut. Um die Dinge zu komplizieren, habe ich Ausnahmen gesehen, bei denen die Ursache auf die Ausnahme selbst hinweist. Hier ist eine rekursive Methode, die wir verwendet haben, die alle Grundlagen für ServletExceptions umfassen:

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