我正在尝试使用持久性运行deleteWhere
查询,但是由于外键冲突,有时此删除操作失败(我不想触发级联删除,我不希望用户如果Supplier
被系统中其他地方的其他实体使用,则可以删除)。从https://github.com/yesodweb/yesod-cookbook/blob/master/cookbook/Handling-Persistence-Exception.md开始,看来我可以使用catch
中的Control.Monad.Catch
。
import Control.Monad.Catch
import qualified Database.Persist as P
import Database.PostgreSQL.Simple.Errors (ConstraintViolation(..))
data DeleteSupplierResult
= DeleteSupplierSuccess
| DeleteSupplierForeignKeyViolation
| DeleteSupplierUncaughtError
deleteSupplier
:: MonadCatch m
=> MonadIO m
=> Key Supplier
-> SqlPersistT m DeleteSupplierResult
deleteSupplier sid =
(DeleteSupplierSuccess <$ deleteSupplierByKey sid) `catch` (return . catchFailures)
where
catchFailures = \case
ForeignKeyViolation _ _ ->
DeleteSupplierForeignKeyViolation
_ ->
DeleteSupplierUncaughtError
deleteSupplierByKey :: MonadIO m => Key Supplier -> SqlPersistT m ()
deleteSupplierByKey key =
P.deleteWhere [SupplierId P.==. key]
是我要匹配ConstraintViolation
的问题,这不是引发的实际异常吗?我如何确定持久性引发的错误并将其捕获?