如果我正确理解您的问题,您想知道如何捕获异常、确定异常是什么并向用户返回消息。有几种方法可以做到这一点。我会告诉你我是怎么做的。
在开始编写代码之前,我可能会提出一些建议。首先,您不需要在服务中显式声明事务(我使用的是 v2.2.5)。服务默认是事务性的(没什么大不了的)。
其次,如果在执行服务方法时发生任何异常,事务将自动回滚。
第三,我建议从save() 中删除failOnError:true(我认为它不适用于delete()...我可能错了?)。我发现在服务中运行validate() 或save() 然后将模型实例返回到控制器更容易,在该控制器中可以在闪存消息中使用对象错误。
以下是我喜欢如何使用服务方法和控制器中的 try/catch 处理异常和保存的示例:
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