我有一个服务方法,可以在事务中执行某些操作。
public User method1() {
// some code...
Vehicle.withTransaction { status ->
// some collection loop
// some other delete
vehicle.delete(failOnError:true)
}
if (checkSomething outside transaction) {
return throw some user defined exception
}
return user
}
如果存在运行时异常,我们不必捕获该异常,并且事务将自动回滚。但是如何确定该事务由于某些异常而回滚,并且我想抛出一些用户友好的错误消息。 delete()调用也不会返回任何内容。
如果我通过捕获Exception(超类)在事务中添加try / catch块,它就不会进入该异常块。但我期待它进入该区块并引发用户友好的例外。
编辑1:最好添加try/catch
arround withTransaction
任何想法如何解决这个问题?提前谢谢。
答案 0 :(得分:1)
如果我理解你的问题是正确的,你想知道如何捕获异常,确定异常是什么,并向用户返回一条消息。有几种方法可以做到这一点。我会告诉你我是怎么做的。
在我开始使用代码之前,我可能会提出一些建议。首先,您不需要在服务中显式声明事务(我使用的是v2.2.5)。默认情况下,服务是交易性的(不是什么大不了的事)。
其次,如果在执行服务方法时发生任何异常,事务将自动回滚。
第三,我建议从failOnError:true
删除save()
(我认为它不适用于delete()
...我可能错了?)。我发现在服务中运行validate()
或save()
更容易,然后将模型实例返回到控制器,在控制器中可以在flash消息中使用对象错误。
以下是我喜欢如何在控制器中使用服务方法和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