squeal-postgresql-0.9.2.0: src/Squeal/PostgreSQL/Session/Exception.hs
{-|
Module: Squeal.PostgreSQL.Session.Exception
Description: exceptions
Copyright: (c) Eitan Chatav, 2019
Maintainer: eitan@morphism.tech
Stability: experimental
exceptions
-}
{-# LANGUAGE
OverloadedStrings
, PatternSynonyms
#-}
module Squeal.PostgreSQL.Session.Exception
( SquealException (..)
, pattern UniqueViolation
, pattern CheckViolation
, pattern SerializationFailure
, pattern DeadlockDetected
, SQLState (..)
, LibPQ.ExecStatus (..)
, catchSqueal
, handleSqueal
, trySqueal
, throwSqueal
) where
import Control.Monad.Catch
import Data.ByteString (ByteString)
import Data.Text (Text)
import qualified Database.PostgreSQL.LibPQ as LibPQ
-- $setup
-- >>> import Squeal.PostgreSQL
-- | the state of LibPQ
data SQLState = SQLState
{ sqlExecStatus :: LibPQ.ExecStatus
, sqlStateCode :: ByteString
-- ^ https://www.postgresql.org/docs/current/static/errcodes-appendix.html
, sqlErrorMessage :: ByteString
} deriving (Eq, Show)
-- | `Exception`s that can be thrown by Squeal.
data SquealException
= SQLException SQLState
-- ^ SQL exception state
| ConnectionException Text
-- ^ `Database.PostgreSQL.LibPQ` function connection exception
| DecodingException Text Text
-- ^ decoding exception function and error message
| ColumnsException Text LibPQ.Column
-- ^ unexpected number of columns
| RowsException Text LibPQ.Row LibPQ.Row
-- ^ too few rows, expected at least and actual number of rows
deriving (Eq, Show)
instance Exception SquealException
-- | A pattern for unique violation exceptions.
pattern UniqueViolation :: ByteString -> SquealException
pattern UniqueViolation msg =
SQLException (SQLState LibPQ.FatalError "23505" msg)
-- | A pattern for check constraint violation exceptions.
pattern CheckViolation :: ByteString -> SquealException
pattern CheckViolation msg =
SQLException (SQLState LibPQ.FatalError "23514" msg)
-- | A pattern for serialization failure exceptions.
pattern SerializationFailure :: ByteString -> SquealException
pattern SerializationFailure msg =
SQLException (SQLState LibPQ.FatalError "40001" msg)
-- | A pattern for deadlock detection exceptions.
pattern DeadlockDetected :: ByteString -> SquealException
pattern DeadlockDetected msg =
SQLException (SQLState LibPQ.FatalError "40P01" msg)
-- | Catch `SquealException`s.
catchSqueal
:: MonadCatch m
=> m a
-> (SquealException -> m a) -- ^ handler
-> m a
catchSqueal = catch
-- | Handle `SquealException`s.
handleSqueal
:: MonadCatch m
=> (SquealException -> m a) -- ^ handler
-> m a -> m a
handleSqueal = handle
-- | `Either` return a `SquealException` or a result.
trySqueal :: MonadCatch m => m a -> m (Either SquealException a)
trySqueal = try
-- | Throw `SquealException`s.
throwSqueal :: MonadThrow m => SquealException -> m a
throwSqueal = throwM