Skip to content
Merged
22 changes: 19 additions & 3 deletions log-base/src/Log/Monad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,25 @@ instance MonadReader r m => MonadReader r (LogT m) where
ask = lift ask
local = mapLogT . local

-- | Run a 'LogT' computation.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove the haddock?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I'm stupid 😬

-- | Run a 'LogT' computation and log any uncaught exceptions.
--
-- Note that in the case of asynchronous/bulk loggers 'runLogT'
-- doesn't guarantee that all messages are actually written to the log
-- once it finishes. Use 'withPGLogger' or 'withElasticSearchLogger'
-- for that.
runLogT :: Text -- ^ Application component name to use.
runLogT :: (MonadBaseControl IO m)
=> Text -- ^ Application component name to use.
-> Logger -- ^ The logging back-end to use.
-> LogLevel -- ^ The maximum log level allowed to be logged.
-- Only messages less or equal than this level with be logged.
-> LogT m a -- ^ The 'LogT' computation to run.
-> m a
runLogT component logger maxLogLevel m = runReaderT (unLogT m) LoggerEnv {
runLogT component logger maxLogLevel m = runReaderT
(unLogT $ liftedCatch m (\(SomeException e) -> do
logAttention "Uncaught exception" $ object ["error" .= show e]
E.throw e)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
E.throw e)
liftBase $ E.throwIO e)

)
LoggerEnv {
leLogger = logger
, leComponent = component
, leDomain = []
Expand All @@ -67,6 +73,16 @@ runLogT component logger maxLogLevel m = runReaderT (unLogT m) LoggerEnv {
} -- We can't do synchronisation here, since 'runLogT' can be invoked
-- quite often from the application (e.g. on every request).

-- Generalized version of catch taken from `lifted-base`
liftedCatch :: (MonadBaseControl IO m, Exception e)
=> m a -- ^ The computation to run
-> (e -> m a) -- ^ Handler to invoke if an exception is raised
-> m a
liftedCatch a handler = control $ \runInIO ->
E.catch
(runInIO a)
(\e -> runInIO $ handler e)

-- | Transform the computation inside a 'LogT'.
mapLogT :: (m a -> n b) -> LogT m a -> LogT n b
mapLogT f = LogT . mapReaderT f . unLogT
Expand Down