    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 :: Controller s a -> Controller s b -> Controller s a
    onException act :: Controller s a
    act handler :: Controller s b
    handler = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
    -> Controller s a
    forall (b :: * -> *) (m :: * -> *) a.
    MonadBaseControl b m =>
    (RunInBase m b -> b (StM m a)) -> m a
    control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
     -> Controller s a)
    -> (RunInBase (ControllerT s IO) IO
        -> IO (StM (ControllerT s IO) a))
    -> Controller s a
    forall a b. (a -> b) -> a -> b
    $ \runInM :: RunInBase (ControllerT s IO) IO
    runInM -> do
      Controller s a -> IO (StM (ControllerT s IO) a)
    RunInBase (ControllerT s IO) IO
    runInM Controller s a
    act IO (Either Response a, s)
    -> IO (Either Response b, s) -> IO (Either Response a, s)
    forall a b. IO a -> IO b -> IO a
    `E.onException` Controller s b -> IO (StM (ControllerT s IO) b)
    RunInBase (ControllerT s IO) IO
    runInM Controller s b
    handler

    finally :: Controller s a -> Controller s b -> Controller s a
    finally :: Controller s a -> Controller s b -> Controller s a
    finally act :: Controller s a
    act next :: Controller s b
    next = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
    -> Controller s a
    forall (b :: * -> *) (m :: * -> *) a.
    MonadBaseControl b m =>
    (RunInBase m b -> b (StM m a)) -> m a
    control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
     -> Controller s a)
    -> (RunInBase (ControllerT s IO) IO
        -> IO (StM (ControllerT s IO) a))
    -> Controller s a
    forall a b. (a -> b) -> a -> b
    $ \runInM :: RunInBase (ControllerT s IO) IO
    runInM -> ((forall a. IO a -> IO a) -> IO (Either Response a, s))
    -> IO (StM (ControllerT s IO) a)
    forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
    E.mask (((forall a. IO a -> IO a) -> IO (Either Response a, s))
     -> IO (StM (ControllerT s IO) a))
    -> ((forall a. IO a -> IO a) -> IO (Either Response a, s))
    -> IO (StM (ControllerT s IO) a)
    forall a b. (a -> b) -> a -> b
    $ \restore :: forall a. IO a -> IO a
    restore -> do
      (Either Response a, s)
    r <- IO (Either Response a, s) -> IO (Either Response a, s)
    forall a. IO a -> IO a
    restore (Controller s a -> IO (StM (ControllerT s IO) a)
    RunInBase (ControllerT s IO) IO
    runInM Controller s a
    act) IO (Either Response a, s)
    -> IO (Either Response b, s) -> IO (Either Response a, s)
    forall a b. IO a -> IO b -> IO a
    `E.onException` (Controller s b -> IO (StM (ControllerT s IO) b)
    RunInBase (ControllerT s IO) IO
    runInM Controller s b
    next)
      (Either Response b, s)
    _ <- Controller s b -> IO (StM (ControllerT s IO) b)
    RunInBase (ControllerT s IO) IO
    runInM Controller s b
    next
      (Either Response a, s) -> IO (Either Response a, s)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either Response a, s)
    r

    bracket :: Controller s a -> (a -> Controller s b)
            -> (a -> Controller s c) -> Controller s c
    bracket :: Controller s a
    -> (a -> Controller s b) -> (a -> Controller s c) -> Controller s c
    bracket aquire :: Controller s a
    aquire release :: a -> Controller s b
    release act :: a -> Controller s c
    act = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) c))
    -> Controller s c
    forall (b :: * -> *) (m :: * -> *) a.
    MonadBaseControl b m =>
    (RunInBase m b -> b (StM m a)) -> m a
    control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) c))
     -> Controller s c)
    -> (RunInBase (ControllerT s IO) IO
        -> IO (StM (ControllerT s IO) c))
    -> Controller s c
    forall a b. (a -> b) -> a -> b
    $ \runInM :: RunInBase (ControllerT s IO) IO
    runInM -> ((forall a. IO a -> IO a) -> IO (Either Response c, s))
    -> IO (StM (ControllerT s IO) c)
    forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
    E.mask (((forall a. IO a -> IO a) -> IO (Either Response c, s))
     -> IO (StM (ControllerT s IO) c))
    -> ((forall a. IO a -> IO a) -> IO (Either Response c, s))
    -> IO (StM (ControllerT s IO) c)
    forall a b. (a -> b) -> a -> b
    $ \restore :: forall a. IO a -> IO a
    restore -> do
      let release' :: (Either Response a, s) -> IO (StM (ControllerT s IO) b)
    release' a :: (Either Response a, s)
    a = Controller s b -> IO (StM (ControllerT s IO) b)
    RunInBase (ControllerT s IO) IO
    runInM (Controller s b -> IO (StM (ControllerT s IO) b))
    -> Controller s b -> IO (StM (ControllerT s IO) b)
    forall a b. (a -> b) -> a -> b
    $ StM (ControllerT s IO) a -> Controller s a
    forall (b :: * -> *) (m :: * -> *) a.
    MonadBaseControl b m =>
    StM m a -> m a
    restoreM (Either Response a, s)
    StM (ControllerT s IO) a
    a Controller s a -> (a -> Controller s b) -> Controller s b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> Controller s b
    release
      (Either Response a, s)
    a <- Controller s a -> IO (StM (ControllerT s IO) a)
    RunInBase (ControllerT s IO) IO
    runInM Controller s a
    aquire
      (Either Response c, s)
    r <- (IO (Either Response c, s) -> IO (Either Response c, s)
    forall a. IO a -> IO a
    restore (IO (Either Response c, s) -> IO (Either Response c, s))
    -> IO (Either Response c, s) -> IO (Either Response c, s)
    forall a b. (a -> b) -> a -> b
    $ Controller s c -> IO (Either Response c, s)
    RunInBase (ControllerT s IO) IO
    runInM (Controller s c -> IO (Either Response c, s))
    -> Controller s c -> IO (Either Response c, s)
    forall a b. (a -> b) -> a -> b
    $ StM (ControllerT s IO) a -> Controller s a
    forall (b :: * -> *) (m :: * -> *) a.
    MonadBaseControl b m =>
    StM m a -> m a
    restoreM (Either Response a, s)
    StM (ControllerT s IO) a
    a Controller s a -> (a -> Controller s c) -> Controller s c
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> Controller s c
    act) IO (Either Response c, s)
    -> IO (Either Response b, s) -> IO (Either Response c, s)
    forall a b. IO a -> IO b -> IO a
    `E.onException` (Either Response a, s) -> IO (StM (ControllerT s IO) b)
    release' (Either Response a, s)
    a
      (Either Response b, s)
    _ <- (Either Response a, s) -> IO (StM (ControllerT s IO) b)
    release' (Either Response a, s)
    a
      (Either Response c, s) -> IO (Either Response c, s)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either Response c, s)
    r

    handle :: E.Exception e => (e -> Controller s a) -> Controller s a
           -> Controller s a
    handle :: (e -> Controller s a) -> Controller s a -> Controller s a
    handle handler :: e -> Controller s a
    handler act :: Controller s a
    act = (RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
    -> Controller s a
    forall (b :: * -> *) (m :: * -> *) a.
    MonadBaseControl b m =>
    (RunInBase m b -> b (StM m a)) -> m a
    control ((RunInBase (ControllerT s IO) IO -> IO (StM (ControllerT s IO) a))
     -> Controller s a)
    -> (RunInBase (ControllerT s IO) IO
        -> IO (StM (ControllerT s IO) a))
    -> Controller s a
    forall a b. (a -> b) -> a -> b
    $ \runInM :: RunInBase (ControllerT s IO) IO
    runInM -> do
      (e -> IO (Either Response a, s))
    -> IO (Either Response a, s) -> IO (Either Response a, s)
    forall e a. Exception e => (e -> IO a) -> IO a -> IO a
    E.handle (Controller s a -> IO (Either Response a, s)
    RunInBase (ControllerT s IO) IO
    runInM (Controller s a -> IO (Either Response a, s))
    -> (e -> Controller s a) -> e -> IO (Either Response a, s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . e -> Controller s a
    handler) (IO (Either Response a, s) -> IO (StM (ControllerT s IO) a))
    -> IO (Either Response a, s) -> IO (StM (ControllerT s IO) a)
    forall a b. (a -> b) -> a -> b
    $ Controller s a -> IO (StM (ControllerT s IO) a)
    RunInBase (ControllerT s IO) IO
    runInM Controller s a
    act