如何在ajax请求中处理Grails异常?

3
如果我正在进行常规请求,我可以在UrlMappings.groovy中定义错误和异常的处理方式,如下面的示例所示:
    "403"(controller: 'error', action: 'index', params:['code':'403'])
    "404"(controller: 'error', action: 'index', params:['code':'404'])
    "500"(controller: 'error', action: 'index', params:['code':'500'])
    "500"(controller: 'home', action: 'noPrivileges', exception: IllegalOperationException)

我可以在特定控制器中处理错误,并呈现我选择的视图,例如:
class ErrorController {

    def index = {
        render view: "/errors/myErrorPage", model: [code: params.code]
    }
}

这个方法非常完美,每当服务器出现错误时,我都会得到我的错误页面。

现在,我如何实现同样的行为以处理ajax请求呢?我使用grails的remoteFunctionformRemote进行ajax请求。每当服务器上发生异常时,我想在javascript中执行相同的代码(例如,我想显示一个带有alert('There was an exception')的警告框)。

上述描述的方法对于ajax请求无效。我仍然会收到一个错误,并且即使在错误中有myErrorPage.gsp的内容,它也不会打印到我用formRemote或remoteFunction的update参数指定的html元素中。

3个回答

6

我最终找到了一种完全干净的解决方案,与处理标准请求的方法兼容。

您需要修改处理错误的操作,如下面的示例:

class ErrorController {

    def index = {
        if (request.xhr) {
             response.status = 200
             render template: "/errors/myAjaxErrorTemplate", model: [code: params.code]
        } else {
             render view: "/errors/myErrorPage", model: [code: params.code]
        }
    }
}

通过request.xhr,您可以区分ajax请求和标准请求。在ajax请求中,您还需要告诉grails将响应状态设置为200,以表示响应正常。

非常好而且简洁。 :) 我很惊讶这个问题在谷歌上找不到答案...


1

remoteFunction 触发了一些事件,包括 onFailureon_ERROR_CODE。您可以使用这些事件来显示警告消息。

您可以在 文档 中查看更多详细信息。


谢谢您的回答,但这不是我想问的。这样做,我必须修改代码中的每个formRemote和remoteFunction。但这并不是这种方法最糟糕的缺点。它还不允许我根据从服务器抛出的异常类型有所不同地采取行动。您有什么想法如何实现这一点吗? - Palo
是的,你可以在错误代码on_ERROR_CODE中替换_ERROR_CODE为你的错误信息。例如,on500(alert('发生了严重错误')),on404(alert('错误404'))等等。你可以创建一个JavaScript函数,并传递代码on500(myFunction('500')),on404(myFunction('404'))。也许你可以使用jQuery来注入这段代码。 - AA.
是的,但我想根据异常类型显示消息,而不是错误代码类型。所有我的异常都有相同的错误代码500。 - Palo
你需要查看jQuery文档:http://api.jquery.com/jQuery.ajax/,其中有一个`error`参数,它是一个带有三个参数的函数,第三个参数是`errorThrow`。虽然我不是jQuery专家,但我猜你可以在这里找到解决方案。 - AA.

0
如果请求状态设置正确,您可以通过remoteFunction/formRemoteonFailure属性定义一个JavaScript函数。
在此函数中,您可以处理客户端异常。
使用文档中的示例,它可能如下所示:
<select onchange="${remoteFunction(action: 'bookByName',
                       update: [success: 'great', failure: 'ohno'],
                       params: '\'bookName=\' + this.value'),
                       onFailure: 'handleError'}">
    <option>first</option>
    <option>second</option>
</select>

谢谢您的回答,但这不是我想问的。这样做,我必须修改代码中的每个formRemote和remoteFunction。但这并不是这种方法最糟糕的缺点。它还不允许我根据从服务器抛出的异常类型有所不同地采取行动。您有什么想法如何实现这一点吗? - Palo
在你的 JavaScript 函数 handleError 中,你可以像这样访问响应的 statusfunction handleError(response) {alert(reponse.status)} - 这样你就可以单独处理每个状态... - aiolos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接