【问题标题】:Why does Grails strip my exceptions?为什么 Grails 会剥离我的异常?
【发布时间】:2026-01-25 09:45:01
【问题描述】:

如果你把它放在控制器动作中:

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

Grails 的错误调试页面(最重要的是日志)只会显示内部异常类及其消息:

错误 500:内部服务器错误

URI: /...
类: java.lang.RuntimeException
消息: 内部

这是有问题的,因为当您选择使用更具描述性的消息来包装异常时,大多数时候外部消息在调试问题时更为重要。

实际上,在原因链中包含所有异常以及它们的类名、消息和堆栈跟踪会很有用,就像常规 Java 所做的那样。

我自己尝试在错误页面中打印异常,但剥离发生在调用错误视图之前。

是否有可以改变这种行为的配置参数?

编辑:我有 posted a bugstarted a mailing list thread,但到目前为止我还没有找到解决方法,甚至没有找到 Grails 源代码中发生这种剥离的位置。

【问题讨论】:

    标签: exception grails groovy error-handling


    【解决方案1】:

    试试this:

    您可以通过将 grails.full.stacktrace VM 属性设置为“true”来完全禁用堆栈跟踪过滤,即将 -Dgrails.full.stacktrace=true 选项添加到您的应用程序启动脚本中。

    【讨论】:

    • 不。它使堆栈跟踪变得更长,但顶部消息仍然是“内部”而不是“外部”。
    【解决方案2】:

    我找到了剥离异常的地方。

    它在org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver.resolveException() 中,它调用了以下方法:

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

    这会测试当前异常是 InvokerInvocationException 还是 GrailsMVCException,这是由控制器内部的用户代码引发的情况,然后通过getRootCause()

    丢弃所有外部异常 >

    这显然是一个错误。

    我还发现原来的异常可以在request."javax.servlet.error.exception"找到

    【讨论】:

      最近更新 更多