2014-12-19 12 views
7

Jeśli umieścisz to w akcji kontrolera:Dlaczego Grails usuwa moje wyjątki?

def inner = new RuntimeException("inner") 
def middle = new Exception("middle", inner) 
def outer = new IllegalArgumentException("outer", middle) 
throw outer 

stronie błąd debugowania Grails' (i, co najważniejsze, dzienniki) pokaże tylko wewnętrzną klasę wyjątku i swoją wiadomość:

Error 500 : Serwer wewnętrzny błąd

URI:/...
Klasa: java.lang.RuntimeException
Wiadomość: wewnętrzna

Jest to problematyczne, ponieważ jeśli zdecydujesz się owinąć wyjątek z komunikatem bardziej opisową, w większości przypadków jest to zewnętrzna wiadomość, że ważniejsze jest w debugowania problemu.

Właściwie, byłoby użyteczne mieć wszystkie wyjątki w łańcuchu przyczyn, z ich nazwą klasy, komunikatem i śledzeniem stosu, tak jak robi to zwykła Java.

Próbowałem już sam wydrukować wyjątek na stronie błędu, ale usuwanie jest wykonywane przed wywołaniem widoku błędu.

Czy istnieje jakiś parametr konfiguracyjny, który może zmienić to zachowanie?

Edycja: Mam posted a bug i started a mailing list thread, ale do tej pory nie znalazłem obejścia, ani nawet miejsca w kodzie źródłowym Grails, gdzie to zdejmuje się.

Odpowiedz

0

Znalazłem miejsce, w którym wyjątki są rozebrane.

Jest w org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver.resolveException() który wywołuje następujące metody:

protected Exception findWrappedException(Exception e) { 
    if ((e instanceof InvokerInvocationException)||(e instanceof GrailsMVCException)) { 
     Throwable t = getRootCause(e); 
     if (t instanceof Exception) { 
      e = (Exception) t; 
     } 
    } 
    return e; 
} 

tej testów czy bieżący wyjątek stanowi InvokerInvocationException lub GrailsMVCException, który jest w przypadku, gdy jest podniesiona za pomocą kodu użytkownika wewnątrz sterownika, a następnie rzuca poza wszystkimi wyjątkami zewnętrznymi do getRootCause()

To jest oczywiście błąd.

Odkryłem również, że oryginalny wyjątek można znaleźć w request."javax.servlet.error.exception"

1

Spróbuj this:

Można całkowicie wyłączyć filtrowanie StackTrace ustawiając grails.full.stacktrace własność VM na „true”, czyli dodać -Dgrails.full.stacktrace = true opcję do skryptu uruchamiania aplikacji .

+1

Nie. To sprawia, że ​​stacktrace znacznie dłużej, ale górna wiadomość jest nadal "wewnętrzna" zamiast "zewnętrzna". – Tobia