21

私は、UrlMappings と汎用例外処理用の ErrorController を使用して Grails で汎用例外処理を行う方法を知っています。これにより、例外がコントローラーをエスケープした場合、ユーザーは汎用エラー ページに送られ、例外がログに記録されます。また、try/catch ブロックを使用して特定の例外を処理し、それらからの回復を試みる方法も知っています。

しかし、ほとんどのコントローラーでは、例外が発生した場合に、もう少し具体的なエラー メッセージをユーザーに表示したいだけです。したがって、作成アクションでは、アイテムが作成されなかったことをユーザーに伝えたいと思います。または、インポート アクションで、インポートが失敗したことをユーザーに伝えたい。現在、コントローラーは次のようになっています。

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 アプリケーションにも同様の要件があると思います。例外が発生したアクションに基づいて異なるエラー メッセージを指定する慣用的な方法は何ですか?

この問題を解決する特定の方法の経験から得られる回答、または実際の解決策を確認できるコードベースへのリンクに興味があります。

4

2 に答える 2

2

エラー 500 (Grails) がスローされた場所を知る方法も参照してください。

コントローラーの注釈に基づいてカスタム エラー ページを作成し、複数のコントローラーに共通の例外処理手順を提供します。

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'
}
于 2013-11-19T15:59:09.447 に答える