Я бы хотел, чтобы мой обработчик по умолчанию мог перехватывать все исключения, которые выбрасывает мое приложение, но для того, чтобы это произошло, мне нужно вручную вызвать повышение после добавления вручную некоторого исключения, перехватывающего мой код ввода-вывода.
ниже приведен пример минимального сервера:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import Web.Scotty.Trans
import Control.Monad.Trans
import Control.Monad.Reader
import Control.Monad.Catch
import Control.Monad.Except
import Data.Text.Lazy as TL
data AppEnv = AppEnv
{ appStuff :: String
}
newtype App a = App
{ unApp :: ReaderT AppEnv IO a
} deriving (Functor, Applicative, Monad, MonadIO, MonadReader AppEnv, MonadThrow)
someFunc :: IO ()
someFunc = do
let run a = runReaderT (unApp $ App a) (AppEnv "APPY STUFF")
scottyT 8080 run $ do
defaultHandler $ \(e :: TL.Text) -> do
liftIO $ print "HERE"
liftIO $ print $ showError e
html $ "Something Went Seriously Wrong"
get "/" $ do
(r :: (Either TL.Text String)) <- liftIO $ runExceptT $ do
(uId) <- lift $ readFile "./helloworld.txt"
return $ ("hello")
liftIO $ print r
case r of
Left l -> raise l
Right s -> (html "hello world")
get "/catch-this" $ do
error "Catch Me"
(html "hello world")
notFound $ do
html "That is not a valid route"
Я хотел бы иметь возможность перехватывать все мои неперехваченные исключения в моем обработчике по умолчанию, однако это не стандартное поведение Скотти, которое происходит, только если вы Звоните raise
. Я мог бы обернуть все свои блоки кода ActionM в ExceptT
, однако это кажется грязным / механическим способом решения этой проблемы. В основном я хочу сделать это для целей ведения журнала, чтобы я мог сообщать в Sentry или Log в файл, и это сделало бы его намного более удобным.