如何知道从哪里抛出错误500(Grails)

时间:2011-03-30 19:13:54

标签: grails error-handling url-mapping

我的UrlMappings.groovy中有下一个场景:

"/user/$action?" (controller:"user")
"/admin/$action?" (controller:"user")

"500"(controller:"error", action:"show")
"404"(controller:"error", action:"show")

我需要知道errorController从哪个控制器抛出引发错误500的异常(如果有的话),并为用户和管理员显示不同的错误页面。

有什么想法吗?

提前致谢。

5 个答案:

答案 0 :(得分:12)

您可以通过request.exception访问ErrorController中的异常。顶级异常始终指向抛出它的控制器,因此您可以使用exception.className找到控制器名称。这是一个非常简单的例子。

class ErrorController {

    def show = {
      def exception = request.exception
      render(text: "Exception in ${exception?.className}", 
        contentType: "text/plain", encoding: "UTF-8")
    }
}

答案 1 :(得分:7)

使用request.getAttribute("exception"),您将获得例外。我将查看所有请求属性,也许直接引用原始控制器。

<强>更新

诀窍在于Grails将抛出的异常包装到GrailsWrappedRuntimeException中,从而可以轻松访问负责异常的代码。在错误控制器中使用以下代码段:

import org.codehaus.groovy.grails.web.errors.GrailsWrappedRuntimeException
def action = {   
   def exception = request.getAttribute('exception')
   if (exception instanceof GrailsWrappedRuntimeException) {
       log.error "exception $exception.className, line $exception.lineNumber has throw $exception.cause"
   }
}

答案 2 :(得分:1)

要显示不同的“错误500”页面,我认为您可以使用Grails脚手架进行相同的操作:

首先,我们只需要在URL Mapping中指定视图:

"500"(view: "/500")   // Point to 500.gsp

然后这是“500”视图代码:

        <h1>Grails Runtime Exception</h1>

        <h2>Error Details</h2>

        <div class="message">
            <strong>Error ${request.'javax.servlet.error.status_code'}:</strong>
            ${request.'javax.servlet.error.message'.encodeAsHTML()}<br/>
            <strong>Servlet:</strong> ${request.'javax.servlet.error.servlet_name'}<br/>
            <strong>URI:</strong> ${request.'javax.servlet.error.request_uri'}<br/>
            <g:if test="${exception}">
                <strong>Exception Message:</strong> ${exception.message?.encodeAsHTML()} <br/>
                <strong>Caused by:</strong> ${exception.cause?.message?.encodeAsHTML()} <br/>
                <strong>Class:</strong> ${exception.className} <br/>
                <strong>At Line:</strong> [${exception.lineNumber}] <br/>
                <strong>Code Snippet:</strong><br/>

                <div class="snippet">
                    <g:each var="cs" in="${exception.codeSnippet}">
                        ${cs?.encodeAsHTML()}<br/>
                    </g:each>
                </div>
            </g:if>
        </div>
        <g:if test="${exception}">
            <h2>Stack Trace</h2>

            <div class="stack">
                <pre><g:each in="${exception.stackTraceLines}">${it.encodeAsHTML()}<br/></g:each></pre>
            </div>
        </g:if>

您可以从错误和提取中提取所需的任何信息。 stacktrace(div class =“stack”)。

您可以为用户和&amp ;;制作2个不同的模板admin,然后g:if标记将决定视图中包含哪些模板。

答案 3 :(得分:0)

您可以通过请求属性org.codehaus.groovy.grails.CONTROLLER访问处理错误请求的Controller实例,例如(在GSP中):

Controller: ${request['org.codehaus.groovy.grails.CONTROLLER']}

获取控制器的名称:

Controller name: ${request['org.codehaus.groovy.grails.CONTROLLER_NAME_ATTRIBUTE']}

我在Grails 2.0和2.2中对此进行了测试,但我无法在任何地方找到它,因此在不同版本的Grails中可能会有所不同。要查看请求中的所有可用属性,请将以下内容添加到error.gsp

${${request.findAll { true }}

答案 4 :(得分:0)

我有时使用我想在错误消息中显示的描述来注释我的控制器:

// ControllerType is a custom annotation
@ControllerType(description= "this does foo bar")
class MainController {
    ...

有了这个,并根据Aoi Karasu的帖子,这里是如何从初始控制器中提取信息:

class ErrorsController {
def index() {
    def initialController = request.exception?.className
    if (initialController) {
        def controller = grailsApplication.getArtefact("Controller", initialController).getReferenceInstance()
        render "Controller: ${initialController}, annotations ${controller.getClass().getDeclaredAnnotations()}"
        return
    }
    render 'no initial controller'
}

}

request.exception?.className grailsApplication.getArtefact 相结合,可以检索控制器,例如,您可以从中提取注释