Можно ли перехватывать / обрабатывать исключения, генерируемые контроллером Grails? Aop?

class MyController {
   def myAction = {
      throw new MyException("Test")
   }
}

Можно ли перехватить / обработать исключение, сгенерированное кодом выше? Следующее отображение url вроде работает, но оно вызывает регистрацию исключения, что раздражает, потому что в моем случае я могу его обработать.

"500"(controller: "error", action: 'myExceptionHandler', exception: MyException)

Почему бы мне не обернуть код, который может вызвать исключение в try / catch? Ну, у меня есть несколько действий, которые могут вызвать одно и то же исключение. Обертывание каждого из них в try / catch нарушает принцип DRY.

3 ответа

Как насчет этой удивительной картины.

http://grails.1312388.n4.nabble.com/Possible-to-get-the-errorhandler-calling-a-controller-closure-td1354335.html

class UrlMappings {
    static mappings = {
      "/$controller/$action?/$id?" {
          constraints { // apply constraints here  }
      }
    "500"(controller:'system', action:'error')
}

class SystemController {
    def error = {
        // Grails has already set the response status to 500

        // Did the original controller set a exception handler?
        if (request.exceptionHandler) {
            if (request.exceptionHandler.call(request.exception)) {
                return
            }           
            // Otherwise exceptionHandler did not want to handle it
        }       
        render(view:"/error")        
    }
}

class MyAjaxController {

    def beforeInterceptor = {
        request.exceptionHandler = { ex ->
            //Do stuff           
            return true
        }
    }

    def index = {
        assert false
    }
}

Существует способ иметь общую обработку исключений с использованием Grails.

Прежде всего, в вашем файле UrlMapping вы можете объявить отображения следующим образом:

"500" (controller: "foo", action: "bar", exception: FooBarException)

Имейте в виду, однако, что это затопит ваши файлы журнала сообщениями об ошибках. В зависимости от конкретного варианта использования это может или не может быть то, что вы хотите.

Если вам не нужны сообщения об ошибках, вы можете использовать плагин. Он должен появиться после добавления в Google "декларативной обработки исключений + grails".

Лично я использую следующий подход: я направляю все необычные исключения в ErrorController. Там у меня есть доступ к запросу ["исключение"] и некоторым дополнительным параметрам, таким как оригинальный контроллер и действие (я поместил эту информацию в карту атрибутов запроса вручную, используя фильтр before). Затем я решаю предпринять соответствующие шаги - обычно вызывая какое-то действие на оригинальном контроллере, скажем, fatalError.

Может быть более "правильный" способ сделать это в Grails, но напишите метод, который принимает замыкание и обрабатывает исключение, если это необходимо. Тогда ваш код будет выглядеть примерно так:

class MyController {
   def myAction = {
      handleMyException {
         throw new MyException("Test")
      }
   }
}

Он вводит строку кода, но код обработки исключений, по крайней мере, все в одном месте, и вы получаете преимущество обработки исключения в действии, в котором оно было сгенерировано.

Другие вопросы по тегам