HTML for ServerError; drop mock database effect handler
This commit is contained in:
parent
3f76917c40
commit
13e8a11e83
@ -60,6 +60,7 @@ executable Main
|
|||||||
Handlers
|
Handlers
|
||||||
Logger
|
Logger
|
||||||
Routes
|
Routes
|
||||||
|
Utility
|
||||||
Views
|
Views
|
||||||
build-depends:
|
build-depends:
|
||||||
HELPS
|
HELPS
|
||||||
@ -68,4 +69,4 @@ library
|
|||||||
import: global
|
import: global
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src
|
src
|
||||||
exposed-modules: Core, Database, Handlers, Logger, Routes, Views, Main
|
exposed-modules: Core, Database, Handlers, Logger, Main, Routes, Utility, Views
|
||||||
|
22
src/Core.hs
22
src/Core.hs
@ -1,7 +1,5 @@
|
|||||||
module Core where
|
module Core where
|
||||||
|
|
||||||
import Control.Exception (IOException)
|
|
||||||
import Control.Monad.Catch (catch)
|
|
||||||
import Data.Aeson (FromJSON, ToJSON)
|
import Data.Aeson (FromJSON, ToJSON)
|
||||||
import Data.Pool (Pool)
|
import Data.Pool (Pool)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
@ -11,10 +9,10 @@ import Database.PostgreSQL.Simple.FromRow (FromRow, field, fromRow)
|
|||||||
import Database.PostgreSQL.Simple.ToField (ToField, toField)
|
import Database.PostgreSQL.Simple.ToField (ToField, toField)
|
||||||
import Database.PostgreSQL.Simple.ToRow (ToRow, toRow)
|
import Database.PostgreSQL.Simple.ToRow (ToRow, toRow)
|
||||||
import Effectful
|
import Effectful
|
||||||
import Effectful.Error.Static (Error, throwError)
|
import Effectful.Error.Static (Error)
|
||||||
import Effectful.Reader.Static (Reader)
|
import Effectful.Reader.Static (Reader)
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Servant hiding ((:>), throwError)
|
import Servant hiding ((:>))
|
||||||
import Servant.HTML.Lucid
|
import Servant.HTML.Lucid
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -67,19 +65,3 @@ data LogLevel = Info | Warning | Error
|
|||||||
|
|
||||||
instance ToField LogLevel where
|
instance ToField LogLevel where
|
||||||
toField level = toField (T.pack (show level))
|
toField level = toField (T.pack (show level))
|
||||||
|
|
||||||
--
|
|
||||||
-- Utility
|
|
||||||
--
|
|
||||||
liftIOE :: (IOE :> es, Error ServerError :> es) => IO a -> Eff es a
|
|
||||||
-- Lift IO into Eff and catch IOExceptions
|
|
||||||
liftIOE m = liftIO m `catch` \(e::IOException) -> do
|
|
||||||
-- Log IOExceptions to stdout
|
|
||||||
liftIO $ putStrLn $ "ERROR Exception: " ++ show e
|
|
||||||
-- Throw a custom Servant ServerError
|
|
||||||
throwError $ ServerError
|
|
||||||
{ errHTTPCode = 500
|
|
||||||
, errReasonPhrase = "Internal Server Error"
|
|
||||||
, errBody = "This incident will be investigated."
|
|
||||||
, errHeaders = []
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module Database where
|
module Database where
|
||||||
|
|
||||||
import Core
|
import Core
|
||||||
|
import Utility
|
||||||
|
|
||||||
import Control.Exception (IOException)
|
import Control.Exception (IOException)
|
||||||
import Data.Aeson (ToJSON)
|
import Data.Aeson (ToJSON)
|
||||||
@ -70,28 +71,6 @@ runDatabaseIO = interpret $ \_ -> \case
|
|||||||
=> (Pool Connection) -> (Connection -> IO a) -> Eff es a
|
=> (Pool Connection) -> (Connection -> IO a) -> Eff es a
|
||||||
liftWithPool p f = liftIOE $ withResource p f
|
liftWithPool p f = liftIOE $ withResource p f
|
||||||
|
|
||||||
runDatabaseDebug :: DatabaseExeEffects es
|
|
||||||
=> Eff (Database : es) a -> Eff es a
|
|
||||||
runDatabaseDebug = interpret $ \_ -> \case
|
|
||||||
DatabaseInit -> do
|
|
||||||
liftIOE $ putStrLn "Mocked setup of the database"
|
|
||||||
DatabaseRead (statement, values) -> do
|
|
||||||
liftIOE $ putStrLn
|
|
||||||
$ "Mocked a READ database operation with statement:\n"
|
|
||||||
++ show statement
|
|
||||||
++ "\nValues:\n"
|
|
||||||
++ show values
|
|
||||||
pure []
|
|
||||||
DatabaseRead_ statement -> do
|
|
||||||
liftIOE $ putStrLn "Mocked a READ database operation on all users"
|
|
||||||
pure []
|
|
||||||
DatabaseWrite (statement, values) -> do
|
|
||||||
liftIOE $ putStrLn
|
|
||||||
$ "Mocked a WRITE database operation with statement:\n"
|
|
||||||
++ show statement
|
|
||||||
++ "\nValues:\n"
|
|
||||||
++ show values
|
|
||||||
|
|
||||||
createConnectionPool :: ByteString -> IO (Pool Connection)
|
createConnectionPool :: ByteString -> IO (Pool Connection)
|
||||||
createConnectionPool connectString = newPool $ defaultPoolConfig
|
createConnectionPool connectString = newPool $ defaultPoolConfig
|
||||||
(connectPostgreSQL connectString)
|
(connectPostgreSQL connectString)
|
||||||
|
@ -2,6 +2,7 @@ module Logger where
|
|||||||
|
|
||||||
import Core
|
import Core
|
||||||
import Database
|
import Database
|
||||||
|
import Utility
|
||||||
|
|
||||||
import Data.Time (getCurrentTime, UTCTime)
|
import Data.Time (getCurrentTime, UTCTime)
|
||||||
import Effectful
|
import Effectful
|
||||||
|
@ -47,14 +47,6 @@ runAppEff env = runEff
|
|||||||
. runLoggerPSQL
|
. runLoggerPSQL
|
||||||
. inject
|
. inject
|
||||||
|
|
||||||
runAppDebug :: AppEnv -> AppEff a -> IO (Either ServerError a)
|
|
||||||
runAppDebug env = runEff
|
|
||||||
. runErrorNoCallStack
|
|
||||||
. runReader env
|
|
||||||
. runDatabaseDebug
|
|
||||||
. runLoggerConsole
|
|
||||||
. inject
|
|
||||||
|
|
||||||
port :: Int
|
port :: Int
|
||||||
port = 8080
|
port = 8080
|
||||||
|
|
||||||
|
28
src/Utility.hs
Normal file
28
src/Utility.hs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
module Utility where
|
||||||
|
|
||||||
|
import qualified Views as V
|
||||||
|
|
||||||
|
import Control.Exception (IOException)
|
||||||
|
import Control.Monad.Catch (catch)
|
||||||
|
import Effectful
|
||||||
|
import Effectful.Error.Static (Error, throwError)
|
||||||
|
import Lucid (renderBS)
|
||||||
|
import Servant ( ServerError(..)
|
||||||
|
, errHTTPCode
|
||||||
|
, errReasonPhrase
|
||||||
|
, errBody
|
||||||
|
, errHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
liftIOE :: (IOE :> es, Error ServerError :> es) => IO a -> Eff es a
|
||||||
|
-- Lift IO into Eff and catch IOExceptions
|
||||||
|
liftIOE m = liftIO m `catch` \(e::IOException) -> do
|
||||||
|
-- Log IOExceptions to stdout
|
||||||
|
liftIO $ putStrLn $ "ERROR Exception: " ++ show e
|
||||||
|
-- Throw a custom Servant ServerError
|
||||||
|
throwError $ ServerError
|
||||||
|
{ errHTTPCode = 500
|
||||||
|
, errReasonPhrase = "Internal Server Error"
|
||||||
|
, errBody = renderBS V.internalServerError
|
||||||
|
, errHeaders = []
|
||||||
|
}
|
@ -32,3 +32,10 @@ userHtml user = div_ [] $ do
|
|||||||
|
|
||||||
warning :: String -> Html ()
|
warning :: String -> Html ()
|
||||||
warning s = p_ [class_ "warning"] (toHtml s)
|
warning s = p_ [class_ "warning"] (toHtml s)
|
||||||
|
|
||||||
|
internalServerError :: Html ()
|
||||||
|
internalServerError = baseDoc $ do
|
||||||
|
div_ [ style_ "text-align: center; margin: 3% 0 0 0;" ] $ do
|
||||||
|
h1_ "500 INTERNAL SERVER ERROR"
|
||||||
|
p_ "This issue is probably our fault. \
|
||||||
|
\ Please try again shortly or contact us for help."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user