2014-12-19 10 views
7

Se si mette questo in un azione di controllo:Perché Grails elimina le mie eccezioni?

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

pagina di errore di debug Grails' (e, soprattutto, i registri) mostreranno solo la classe eccezione interna e il suo messaggio:

Errore 500 : Internal Server Error

URI:/...
Classe: java.lang.RuntimeException
Messaggio: interno

Questo è problematico, perché quando si sceglie di avvolgere un'eccezione con un messaggio più descrittivo, la maggior parte delle volte è il messaggio esterno che è più importante per il debug del problema.

In realtà, sarebbe utile avere tutte le eccezioni nella catena delle cause, con il nome della classe, il messaggio e la traccia dello stack, proprio come fa il normale Java.

Ho provato a stampare l'eccezione nella pagina di errore, ma lo spoglio avviene prima che venga richiamata la vista di errore.

Esiste un parametro di configurazione da qualche parte che può modificare questo comportamento?

Modifica: ho posted a bug e started a mailing list thread, ma finora non ho trovato una soluzione alternativa, né nemmeno il posto nel codice sorgente di Grails in cui avviene questo spoglio.

risposta

0

Ho trovato il luogo in cui vengono eliminate le eccezioni.

È in org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver.resolveException() che chiama il seguente metodo:

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

Questa verifica se l'eccezione corrente è un InvokerInvocationException o GrailsMVCException, che è il caso quando è sollevato dal codice utente all'interno di un controllore, e poi tiri via tutte le eccezioni esterne tramite getRootCause()

Questo è chiaramente un bug.

Ho anche trovato che l'eccezione originale può essere trovata in request."javax.servlet.error.exception"

1

Prova this:

È possibile disattivare completamente il filtraggio StackTrace impostando la proprietà VM grails.full.stacktrace su "true", cioè aggiungere l'opzione = true -Dgrails.full.stacktrace allo script di avvio dell'applicazione .

+1

No. Rende lo stacktrace molto più lungo, ma il messaggio principale è ancora "interno" anziché "esterno". – Tobia