我有一个服务方法,它在事务中执行一些操作。
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()调用也不会返回任何东西。
如果我通过捕获异常(超类)在事务中添加try/catch块,则不会进入该异常块。但是我期望它进入那个块并抛出用户友好的异常。
EDIT 1:在withTransaction
周围添加try/catch
是一个好主意吗
你知道怎么解决这个问题吗?
如果我正确理解了您的问题,您想知道如何捕获异常,确定异常是什么,并向用户返回消息。有几种方法可以做到这一点。我来告诉你我是怎么做的。
在我开始写代码之前,我可能会提出一些建议。首先,您不需要在服务中显式声明事务(我使用的是v2.2.5)。服务在默认情况下是事务性的(没什么大不了的)。
第二,如果在执行服务方法时出现任何异常,事务将自动回滚。第三,我建议从save()
中删除failOnError:true
(我不认为它适用于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
其他相关问题的链接可能会有所帮助:
Grails控制器中的异常处理
在Grails 2.2.4中使用ExceptionMapper处理Grails控制器中的异常
https://commons.apache.org/proper/commons lang/javadocs/api - 2.6 -/- org/apache/commons/lang/exception/exceptionutils.html