我在我的play 2 app中有以下代码:
控制器:
... def getUserById(id: Long) = Action.async { try { userService.findById(id) .map(u => Ok(Json.toJson(u)) .recover { case e: Exception => Ok("Exception got") } } } ...
服务:
... override def findAll: Future[Seq[User]] = { throw new Exception("Error 1") } ...
但是在控制器中我无法捕获服务中抛出的异常(以某种方式忽略了恢复块).而是显示标准错误页面,并显示异常"错误1".
我究竟做错了什么?
您的代码在返回之前会抛出异常Future
,因此您应该:
override def findAll: Future[Seq[User]] = Future { throw new Exception("Error 1") }
要不就:
override def findAll: Future[Seq[User]] = Future.failed(new Exception("Error 1"))
以这种方式 - 异常将被包装在Future
实例中,因此每个订阅者都可以异步地获取它并进行处理recover
.否则你必须通过包装来同步处理失败try{ findAll(...) } catch {...}
.
PS抛出异常并不是引用透明的,所以这就是为什么有时候很难理解这种行为.将错误包含在a中的Future
方法更加纯粹,因此我更希望使代码更清晰.