module Mensam.Server.Application.SeldaPool.Servant where

import Mensam.Server.Application.SeldaPool.Class

import Control.Exception
import Control.Monad.Logger.CallStack
import Data.Text qualified as T
import Servant

handleSeldaException ::
  ( Exception e
  , HasStatus r
  , Applicative m
  , IsMember r responses
  ) =>
  Proxy e ->
  r ->
  SeldaResult a ->
  (SeldaResult a -> m (Union responses)) ->
  m (Union responses)
handleSeldaException :: forall e r (m :: * -> *) (responses :: [*]) a.
(Exception e, HasStatus r, Applicative m, IsMember r responses) =>
Proxy e
-> r
-> SeldaResult a
-> (SeldaResult a -> m (Union responses))
-> m (Union responses)
handleSeldaException (Proxy e
Proxy :: Proxy e) r
response SeldaResult a
seldaResult SeldaResult a -> m (Union responses)
handleResult =
  case SeldaResult a
seldaResult of
    SeldaSuccess a
_ -> SeldaResult a -> m (Union responses)
handleResult SeldaResult a
seldaResult
    SeldaFailure SomeException
err ->
      case forall e. Exception e => SomeException -> Maybe e
fromException @e SomeException
err of
        Just e
_ -> do
          r -> m (Union responses)
forall x (xs :: [*]) (f :: * -> *).
(Applicative f, HasStatus x, IsMember x xs) =>
x -> f (Union xs)
respond r
response
        Maybe e
Nothing ->
          SeldaResult a -> m (Union responses)
handleResult SeldaResult a
seldaResult

handleSeldaSomeException ::
  ( HasStatus r
  , MonadLogger m
  , IsMember r responses
  ) =>
  r ->
  SeldaResult a ->
  (a -> m (Union responses)) ->
  m (Union responses)
handleSeldaSomeException :: forall r (m :: * -> *) (responses :: [*]) a.
(HasStatus r, MonadLogger m, IsMember r responses) =>
r
-> SeldaResult a
-> (a -> m (Union responses))
-> m (Union responses)
handleSeldaSomeException r
response SeldaResult a
seldaResult a -> m (Union responses)
handleResult =
  case SeldaResult a
seldaResult of
    SeldaSuccess a
x -> a -> m (Union responses)
handleResult a
x
    SeldaFailure SomeException
err -> do
      Text -> m ()
forall (m :: * -> *). (HasCallStack, MonadLogger m) => Text -> m ()
logWarn (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Handled unexpected Selda failure: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (SomeException -> String
forall a. Show a => a -> String
show SomeException
err)
      r -> m (Union responses)
forall x (xs :: [*]) (f :: * -> *).
(Applicative f, HasStatus x, IsMember x xs) =>
x -> f (Union xs)
respond r
response