首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Grails控制器中的异常处理

Grails控制器中的异常处理
EN

Stack Overflow用户
提问于 2013-06-19 21:20:40
回答 2查看 32K关注 0票数 20

我知道如何在Grails中使用UrlMappings和用于通用异常处理的ErrorController进行通用异常处理,这样,如果异常从控制器中逃脱,用户将被发送到通用错误页面并记录该异常。我还知道如何使用try/catch块来处理特定的异常并尝试从中恢复。

但在大多数控制器中,如果发生异常,我只想给用户一个稍微具体一点的错误消息。因此,在create操作中,我想告诉用户该项目不是创建的。或者在导入操作中,我想告诉用户导入失败。现在,控制器看起来像:

代码语言:javascript
复制
class ThingController {
  def create = {
    try {
      // The real controller code, which quickly hands it off to a service
    } catch (Exception e) {
      handleException(e, "There was an error while attempting to create the Thing")
    }
  }

  def delete = {
    try {
      // The real controller code, which quickly hands it off to a service
    } catch (Exception e) {
      handleException(e, "There was an error while attempting to delete the Thing")
    }
  }

  private void handleException(Exception e, String message) {
    flash.message = message
    String eMessage = ExceptionUtils.getRootCauseMessage(e)
    log.error message(code: "sic.log.error.ExceptionOccurred", args: ["${eMessage}", "${e}"])
    redirect(action:index)
  }
}

请注意,catch块不会根据异常的类型或内容做任何不同的事情;它们只是根据控制器给出稍微更具描述性的错误消息。“真正的”控制器代码通常是6-10行,所以仅仅为了更改错误消息而额外增加4行代码似乎太多了。此外,CodeNarc "CatchException“规则抱怨,这强化了我的观点,即必须有更好的方法来做到这一点。我假设其他Grails应用程序也有类似的需求。根据异常产生的操作指定不同的错误消息的惯用方法是什么?

我对来自解决这个问题的特定方法的经验的答案感兴趣,或者更好的是,链接到我可以在实践中看到解决方案的代码库。

EN

回答 2

Stack Overflow用户

发布于 2013-06-20 07:23:38

Grails具有处理控制器异常的通用机制。您可以在专用的错误控制器中完成此操作。常规控制器不需要使用try/catch。

控制器:

代码语言:javascript
复制
class ThingController {
    def create() {
        def id = params.id as Long

        if (id == null) {
            throw new MissingPropertyException("thingId")
        }
        // The real controller code, which mostly parses things out and hands it
        // off to a service.
        // Service methods can throws exception

    }
}

在UrlMappings中添加处理500错误:

代码语言:javascript
复制
class UrlMappings {

    static mappings = {
        // Exception handling in ErrorController
        "500"(controller: "error")
    }
}

ErrorController:

代码语言:javascript
复制
class ErrorController {

    def index() {

        def exception = request.exception.cause
        def message = ExceptionMapper.mapException(exception)
        def status = message.status

        response.status = status
            render(view: "/error", model: [status: status, exception: exception])
    }
}

您可以使用此方法处理REST和非REST异常。还有一个Declarative Exception Handling插件,但我没有

更新

您可以在error控制器中获取具体的错误消息。当在控制器抛出新的错误时(“试图删除事物时出现错误”),那么在RuntimeException中控制器request.exception.cause.message将显示消息:“试图删除事物时发生错误”。

票数 30
EN

Stack Overflow用户

发布于 2013-11-19 23:59:09

另请参阅How to know from where was thrown error 500 (Grails)

我根据控制器上的注释创建自定义错误页面,给出了跨多个控制器的通用异常处理过程。

代码语言:javascript
复制
class ErrorsController {
def index() {
    def initialController = request.exception?.className
    if (initialController) {
        def controller = grailsApplication.getArtefact("Controller", initialController).getReferenceInstance()
        // do some rendering based on the annotations
        render "Controller: ${initialController}, annotations ${controller.getClass().getDeclaredAnnotations()}"
        return
    }
    render 'no initial controller'
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17192336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档