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
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
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
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