我的UrlMappings.groovy中有下一个场景:
"/user/$action?" (controller:"user")
"/admin/$action?" (controller:"user")
"500"(controller:"error", action:"show")
"404"(controller:"error", action:"show")
我需要知道errorController从哪个控制器抛出引发错误500的异常(如果有的话),并为用户和管理员显示不同的错误页面。
有什么想法吗?
提前致谢。
答案 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 相结合,可以检索控制器,例如,您可以从中提取注释