4
我有一個Play應用程序和幾個模塊,每個模塊都有自己的異常集。這裏有三個例子:Play Framework:如何實現正確的錯誤處理
模塊common
:
package services.common
trait CommonErrors {
final case class NotFound(id: String) extends Exception(s"object $id not found")
final case class InvalidId(id: String) extends Exception(s"$id is an invalid id")
...
// `toJson` is just an extension method that converts an exception to JSON
def toResult(e: Exception): Result = e match {
case NotFound => Results.NotFound(e.toJson)
case InvalidId => Results.BadRequest(e.toJson)
case _ => Results.InternalError(e.toJson)
}
}
模塊auth
:
package services.auth
trait AuthErrors {
final case class UserNotFound(e: NotFound) extends Exception(s"user ${e.id} not found")
final case class UserAlreadyExists(email: String) extends Exception(s"user identified by $email already exists")
...
// `toJson` is just an extension method that converts an exception to JSON
def toResult(e: Exception): Result = e match {
case UserNotFound => Results.NotFound(e.toJson)
case UserAlreadyExists => Results.BadRequest(e.toJson)
case _ => Results.InternalError(e.toJson)
}
}
模塊other
:
trait OtherErrors {
final case class AnotherError(s: String) extends Exception(s"another error: $s")
...
// `toJson` is just an extension method that converts an exception to JSON
def toResult(e: Exception): Result = e match {
case AnotherError => Results.BadRequest(e.toJson)
...
case _ => Results.InternalError(e.toJson)
}
}
正如你可以看到,每個性狀定義一組例外並提供一種方法來轉換該ex ception像這樣的JSON響應:
{
"status": 404,
"code": "not_found",
"message": "user 123456789123456789123456 not found",
"request": "https://myhost.com/users/123456789123456789123456"
}
我試圖做到的,是讓每個模塊定義及其例外,重用common
模塊中定義的那些,和混入異常性狀需要:
object Users extends Controller {
val errors = new CommonErrors with AuthErrors with OtherErrors {
// here I have to override `toResult` to make the compiler happy
override def toResult(e: Exception) = super.toResult
}
def find(id: String) = Action { request =>
userService.find(id).map { user =>
Ok(success(user.toJson))
}.recover { case e =>
errors.toResult(e) // this returns the appropriate result
}
}
}
如果你看一下我是如何覆蓋toResult
,我總是返回super.toResult
,其對應於包含在特質OtherErrors
實施...這實現可能會錯過一些模式,預計在CommonErrors.toResult
被發現。
肯定我錯過了一些東西......所以問題是:什麼是設計模式來解決多個實施toResult
的問題?
很好的解釋...非常感謝! – j3d
很乾淨。我很喜歡 –