Если я правильно понял вас, вы хотите знать, как поймать исключение, определить, что такое исключение, и вернуть сообщение пользователю. Есть несколько способов сделать это. Я покажу вам, как я это делаю.
Прежде чем перейти к коду, я могу предложить несколько вещей. Во-первых, вам не нужно явно объявлять транзакцию в службе (я использую v2.2.5). Услуги являются транзакционными по умолчанию (не большая сделка).
Во-вторых, транзакция будет автоматически откатываться, если любое событие возникает при выполнении метода обслуживания.
В-третьих, я бы рекомендовал удалить failOnError:true
с save()
(я не думаю, что он работает на delete()
... Возможно, я ошибаюсь?). Я считаю, что проще запустить validate()
или save()
в службе, а затем вернуть экземпляр модели контроллеру, где ошибки объектов могут использоваться во флэш-сообщении.
Ниже приведен пример того, как мне нравится обрабатывать исключения и сейв, используя метод обслуживания и попытаться/поймать в контроллере:
class FooService {
def saveFoo(Foo fooInstance) {
return fooInstance.save()
}
def anotherSaveFoo(Foo fooInstance) {
if(fooInstance.validate()){
fooInstance.save()
}else{
do something else or
throw new CustomException()
}
return fooInstance
}
}
class FooController {
def save = {
def newFoo = new Foo(params)
try{
returnedFoo = fooService.saveFoo(newFoo)
}catch(CustomException | Exception e){
flash.warning = [message(code: 'foo.validation.error.message',
args: [org.apache.commons.lang.exception.ExceptionUtils.getRootCauseMessage(e)],
default: "The foo changes did not pass validation.<br/>{0}")]
redirect('to where ever you need to go')
return
}
if(returnedFoo.hasErrors()){
def fooErrors = returnedFoo.errors.getAllErrors()
flash.warning = [message(code: 'foo.validation.error.message',
args: [fooErrors],
default: "The foo changes did not pass validation.<br/>${fooErrors}")]
redirect('to where ever you need to go')
return
}else {
flash.success = [message(code: 'foo.saved.successfully.message',
default: "The foo was saved successfully")]
redirect('to where ever you need to go')
}
}
}
Надеется, что это помогает, или получает какой-то другой вход от более опытного Grails Разработчики.
Вот несколько других способов, которые я нашел, чтобы получить информацию об исключении пройти по своему пользователю:
request.exception.cause
request.exception.cause.message
response.status
Несколько ссылок на другие соответствующие вопросы, которые могут помочь:
Exception handling in Grails controllers
Exception handling in Grails controllers with ExceptionMapper in Grails 2.2.4 best practice
https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html
Спасибо @CheddarMonkey. Поэтому вы рекомендуете окружать сервисный вызов с помощью try/catch. Тогда мой «РЕДАКТИРОВАТЬ 1» в вопросе правильный способ сделать это ?? !! – user2001627
Вы хотите, чтобы try/catch в контроллере вокруг вызова службы, как в примере, где он обертывает 'returnFoo = fooService.saveFoo (newFoo) ' – CheddarMonkey
Да, но в наших контроллерах мы стараемся избегать try/catch и просто просим просто позвонить в службу (службы), и служба поставит ответное сообщение, для которого контроллер должен просто передать его. Потому что в некоторых сценариях у нас есть много разных вызовов для обслуживания api разных классов, тогда контроллер будет заселен try/catch. Спасибо за ваши материалы. – user2001627