如何捕获重复键值违规的光滑 postgres 异常 [英] How to catch slick postgres exceptions for duplicate key value violations

查看:34
本文介绍了如何捕获重复键值违规的光滑 postgres 异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的表在我的 postgresql 数据库中的一对列上有一个唯一索引.

My table has a unique index on a pair of columns in my postgresql database.

我想知道如何在插入时捕获重复的键异常:

I want to know how I can catch a duplicate key exception when I am inserting:

def save(user: User)(implicit session: Session): User = {
  val newId = (users returning users.map(_id) += user
  user.copy(id = newId)
}

我的日志显示此异常:

Execution exception[[PSQLException: ERROR: duplicate key value violates unique constraint "...."

我也没有真正在 Scala 中使用过异常.

I haven't really used exceptions much in scala either yet also.

推荐答案

您的 save 方法可能应该返回与 User 不同的内容,以指示失败的可能性.如果唯一会抛出的异常是唯一键,并且您真的只关心成功或失败(而不是失败的类型),那么一种方法是返回 Option[User].

Your save method should probably return something different than just User, to indicate the possibility of failure. If the only exception that will be thrown is by unique key, and you really only care about success or failure (and not the type of failure), one way to go would be to return Option[User].

你可以使用一个简单的 try/catch 块,将成功的保存映射到 Some[User]PSQLExceptionNone:

You could use a simple try/catch block, mapping successful saves to Some[User] and PSQLException to 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
  }
}

我个人不是这样的,因为 try/catch 并不是真正惯用的 Scala,并且您的错误类型被丢弃.下一个选项是使用 scala.util.Try.

Personally not the way I'd go, as try/catch isn't really idiomatic Scala, and your error type is discarded. The next option is to use 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)
}

这里的代码更简单.如果Try的body成功,则save返回Success[User],否则返回包裹在失败.这将允许您使用 Try 做很多事情.

The code here is simpler. If the body of Try is successful, then save will return Success[User], and if not it will return the exception wrapped in Failure. This will allow you to do many things with 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..")
}

你可以像Option一样使用它:

save(user) map { user =>
   Ok(user)
} getOrElse {
   InternalServerError("Something terrible happened..")
}

您可以一次将多个组合在一起,并在第一次失败时停止:

You can compose many together at once, and stop on the first failure:

(for {
   u1 <- save(user1)
   u2 <- save(user2)
   u3 <- save(user3)
} yield {
  (u1, u2, u3)
}) match {
   case Success((u1, u2, u3)) => Ok(...)
   case Failure(...) => ...
}

这篇关于如何捕获重复键值违规的光滑 postgres 异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆