Skip to content

Commit 366add1

Browse files
committed
[CORE-7914] Log an unhandled exception or a user abort before the computation ends
1 parent 7d51f52 commit 366add1

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

log-base/src/Log/Monad.hs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Control.Monad.State.Class
2424
import Control.Monad.Trans.Control
2525
import Control.Monad.Writer.Class
2626
import Data.Aeson
27-
import Data.Text (Text)
27+
import Data.Text (Text, pack)
2828
import Data.Time
2929
import qualified Control.Monad.Fail as MF
3030
import qualified Control.Exception as E
@@ -46,26 +46,35 @@ instance MonadReader r m => MonadReader r (LogT m) where
4646
ask = lift ask
4747
local = mapLogT . local
4848

49-
-- | Run a 'LogT' computation.
50-
--
51-
-- Note that in the case of asynchronous/bulk loggers 'runLogT'
52-
-- doesn't guarantee that all messages are actually written to the log
53-
-- once it finishes. Use 'withPGLogger' or 'withElasticSearchLogger'
54-
-- for that.
55-
runLogT :: Text -- ^ Application component name to use.
49+
runLogT :: (MonadMask m, MonadBase IO m)
50+
=> Text -- ^ Application component name to use.
5651
-> Logger -- ^ The logging back-end to use.
5752
-> LogLevel -- ^ The maximum log level allowed to be logged.
5853
-- Only messages less or equal than this level with be logged.
5954
-> LogT m a -- ^ The 'LogT' computation to run.
6055
-> m a
61-
runLogT component logger maxLogLevel m = runReaderT (unLogT m) LoggerEnv {
62-
leLogger = logger
63-
, leComponent = component
64-
, leDomain = []
65-
, leData = []
66-
, leMaxLogLevel = maxLogLevel
67-
} -- We can't do synchronisation here, since 'runLogT' can be invoked
68-
-- quite often from the application (e.g. on every request).
56+
runLogT component logger maxLogLevel m =
57+
fst <$> runReaderT
58+
(unLogT $
59+
generalBracket
60+
(pure ())
61+
(\_ -> \case
62+
ExitCaseSuccess _ -> pure ()
63+
ExitCaseException (SomeException e) -> do
64+
logAttention "Uncaught exception raised" $ object ["error" .= (pack . show $ e)]
65+
throwM e
66+
ExitCaseAbort ->
67+
logAttention_ "Process was aborted manually"
68+
)
69+
(const m))
70+
LoggerEnv
71+
{ leLogger = logger
72+
, leComponent = component
73+
, leDomain = []
74+
, leData = []
75+
, leMaxLogLevel = maxLogLevel
76+
} -- We can't do synchronisation here, since 'runLogT' can be invoked
77+
-- quite often from the application (e.g. on every request).
6978

7079
-- | Transform the computation inside a 'LogT'.
7180
mapLogT :: (m a -> n b) -> LogT m a -> LogT n b

0 commit comments

Comments
 (0)