-- Copied from https://github.com/nikita-volkov/hasql-pool/blob/50b49864afc796fd7df6e08706d3a628c656dcf0/src/library/Hasql/Pool/SessionErrorDestructors.hs
module Hasql.Pool.SessionErrorDestructors where

import Data.Text
import qualified Hasql.Errors as Errors
import Hasql.Pool.Prelude

requiresConnectionDiscard :: Errors.SessionError -> Bool
requiresConnectionDiscard :: SessionError -> Bool
requiresConnectionDiscard = \case
  Errors.ConnectionSessionError {} -> Bool
True
  Errors.MissingTypesSessionError {} -> Bool
True
  Errors.ScriptSessionError Text
_ ServerError
serverError -> ServerError -> Bool
isStaleServerError ServerError
serverError
  Errors.StatementSessionError Int
_ Int
_ Text
_ [Text]
_ Bool
_ StatementError
statementError -> StatementError -> Bool
statementRequiresConnectionDiscard StatementError
statementError
  -- Driver errors indicate that Hasql or the server left the connection in an
  -- unexpected state. In particular, Hasql closes the libpq connection when
  -- cleanup after an interruption fails, so it must not be reused by the pool.
  Errors.DriverSessionError {} -> Bool
True

discardDetails :: Errors.SessionError -> Maybe Text
discardDetails :: SessionError -> Maybe Text
discardDetails SessionError
err =
  if SessionError -> Bool
requiresConnectionDiscard SessionError
err
    then Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ SessionError -> Text
forall a. IsError a => a -> Text
Errors.toMessage SessionError
err
    else Maybe Text
forall a. Maybe a
Nothing

statementRequiresConnectionDiscard :: Errors.StatementError -> Bool
statementRequiresConnectionDiscard :: StatementError -> Bool
statementRequiresConnectionDiscard = \case
  Errors.ServerStatementError ServerError
serverError -> ServerError -> Bool
isStaleServerError ServerError
serverError
  Errors.UnexpectedColumnTypeStatementError {} -> Bool
True
  StatementError
_ -> Bool
False

isStaleServerError :: Errors.ServerError -> Bool
isStaleServerError :: ServerError -> Bool
isStaleServerError (Errors.ServerError Text
code Text
_ Maybe Text
_ Maybe Text
_ Maybe Int
_) =
  Text
code Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"0A000" Bool -> Bool -> Bool
|| Text
code Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"XX000"