packages feed

hasql-pool-1.4.2.1: src/library/Hasql/Pool/SessionErrorDestructors.hs

module Hasql.Pool.SessionErrorDestructors where

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

reset :: (Text -> x) -> x -> Errors.SessionError -> x
reset onReset onNoReset = \case
  Errors.ConnectionSessionError details -> onReset details
  _ -> onNoReset

requiresConnectionDiscard :: Errors.SessionError -> Bool
requiresConnectionDiscard = \case
  Errors.ConnectionSessionError {} -> True
  Errors.MissingTypesSessionError {} -> True
  Errors.ScriptSessionError _ serverError -> isStaleServerError serverError
  Errors.StatementSessionError _ _ _ _ _ statementError -> statementRequiresConnectionDiscard 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 {} -> True

discardDetails :: Errors.SessionError -> Maybe Text
discardDetails err =
  if requiresConnectionDiscard err
    then Just $ Errors.toMessage err
    else Nothing

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

isStaleServerError :: Errors.ServerError -> Bool
isStaleServerError (Errors.ServerError code _ _ _ _) =
  code == "0A000" || code == "XX000"