module Web.Simple.Controller.Exception where

import qualified Control.Exception as E
import           Control.Monad.Trans.Control
import           Web.Simple.Controller

onException :: Controller s a -> Controller s b -> Controller s a
onException act handler = control $ \runInM -> do
  runInM act `E.onException` runInM handler

finally :: Controller s a -> Controller s b -> Controller s a
finally act next = control $ \runInM -> E.mask $ \restore -> do
  r <- restore (runInM act) `E.onException` (runInM next)
  _ <- runInM next
  return r

bracket :: Controller s a -> (a -> Controller s b)
        -> (a -> Controller s c) -> Controller s c
bracket aquire release act = control $ \runInM -> E.mask $ \restore -> do
  let release' a = runInM $ restoreM a >>= release
  a <- runInM aquire
  r <- (restore $ runInM $ restoreM a >>= act) `E.onException` release' a
  _ <- release' a
  return r

handle :: E.Exception e => (e -> Controller s a) -> Controller s a
       -> Controller s a
handle handler act = control $ \runInM -> do
  E.handle (runInM . handler) $ runInM act