Bla*_*man 12 scala playframework slick
我的表在postgresql数据库中的一对列上有一个唯一索引.
我想知道在插入时如何捕获重复的键异常:
def save(user: User)(implicit session: Session): User = {
val newId = (users returning users.map(_id) += user
user.copy(id = newId)
}
Run Code Online (Sandbox Code Playgroud)
我的日志显示此异常:
Execution exception[[PSQLException: ERROR: duplicate key value violates unique constraint "...."
Run Code Online (Sandbox Code Playgroud)
我还没有在scala中使用异常.
Mic*_*jac 27
你的save方法应该返回不同的东西User,以表明失败的可能性.如果将抛出的唯一异常是由唯一键,并且您真的只关心成功或失败(而不是失败的类型),一种方法是返回Option[User].
你可以使用一个简单的try/catch块,映射成功保存到Some[User]和 PSQLException到None:
def save(user: User)(implicit session: Session): Option[User] = {
try {
val newId = (users returning users.map(_id) += user
Some(user.copy(id = newId))
} catch {
case PSQLException => None
}
}
Run Code Online (Sandbox Code Playgroud)
个人不是我去的方式,因为try/catch不是真正的惯用Scala,你的错误类型被丢弃.下一个选项是使用scala.util.Try.
def save(user: User)(implicit session: Session): Try[User] = Try {
val newId = (users returning users.map(_id) += user
user.copy(id = newId)
}
Run Code Online (Sandbox Code Playgroud)
这里的代码更简单.如果正文Try成功,那么save将返回Success[User],如果不成功则返回包含的异常Failure.这将允许你做很多事情Try.
你可以模式匹配:
save(user) match {
case Success(user) => Ok(user)
case Failure(t: PSQLException) if(e.getSQLState == "23505") => InternalServerError("Some sort of unique key violation..")
case Failure(t: PSQLException) => InternalServerError("Some sort of psql error..")
case Failure(_) => InternalServerError("Something else happened.. it was bad..")
}
Run Code Online (Sandbox Code Playgroud)
您可以使用它Option:
save(user) map { user =>
Ok(user)
} getOrElse {
InternalServerError("Something terrible happened..")
}
Run Code Online (Sandbox Code Playgroud)
你可以一次组合很多,并在第一次失败时停止:
(for {
u1 <- save(user1)
u2 <- save(user2)
u3 <- save(user3)
} yield {
(u1, u2, u3)
}) match {
case Success((u1, u2, u3)) => Ok(...)
case Failure(...) => ...
}
Run Code Online (Sandbox Code Playgroud)
Ixx*_*Ixx 16
在Slick 3.x中你可以使用asTry.
我正在使用MySQL,但是相同的代码可以用于PostgreSQL,只有异常是不同的.
import scala.util.Try
import scala.util.Success
import scala.util.Failure
db.run(myAction.asTry).map {result =>
result match {
case Success(res) =>
println("success")
// ...
case Failure(e: MySQLIntegrityConstraintViolationException) => {
//code: 1062, status: 23000, e: Duplicate entry 'foo' for key 'name'
println(s"MySQLIntegrityConstraintViolationException, code: ${e.getErrorCode}, sql status: ${e.getSQLState}, message: ${e.getMessage}")
// ...
}
case Failure(e) => {
println(s"Exception in insertOrUpdateListItem, ${e.getMessage}")
// ...
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:也可以映射action(myAction.asTry.map ...)而不是返回的future db.run.
| 归档时间: |
|
| 查看次数: |
8975 次 |
| 最近记录: |