diff --git a/yesod-core/src/Yesod/Core/Class/Yesod.hs b/yesod-core/src/Yesod/Core/Class/Yesod.hs index 553b11cf..21914468 100644 --- a/yesod-core/src/Yesod/Core/Class/Yesod.hs +++ b/yesod-core/src/Yesod/Core/Class/Yesod.hs @@ -75,14 +75,14 @@ class RenderRoute site => Yesod site where approot = guessApproot -- | @since 1.6.24.0 - -- Should we catch an exception, or rethrow it. - -- Rethrowing an exception lets the webserver deal with it - -- (usually warp). - -- catching allows yesod to render the error page. - -- the default 'rethrowAsync' is to rethrow async - -- exceptions. - catchBehavior :: site -> IO a -> (SomeException -> IO a) -> IO a - catchBehavior _ = catch + -- allows the user to specify how exceptions are cought. + -- by default all async exceptions are thrown and synchronous + -- exceptions render a 500 page. + -- One could override this for example to catch all exceptions + -- aside connection closed by peer to let yesod do more 500 page + -- rendering (instead of warp). + catchHandlerExceptions :: site -> IO a -> (SomeException -> IO a) -> IO a + catchHandlerExceptions _ = catch -- | Output error response pages. -- diff --git a/yesod-core/src/Yesod/Core/Internal/Run.hs b/yesod-core/src/Yesod/Core/Internal/Run.hs index e8c361d2..c090ba4c 100644 --- a/yesod-core/src/Yesod/Core/Internal/Run.hs +++ b/yesod-core/src/Yesod/Core/Internal/Run.hs @@ -99,7 +99,7 @@ basicRunHandler rhe handler yreq resState = do -- Run the handler itself, capturing any runtime exceptions and -- converting them into a @HandlerContents@ - contents' <- unsafeAsyncCatch (rheShouldCatch rhe) + contents' <- unsafeAsyncCatch (rheCatchHandlerExceptions rhe) (do res <- unHandlerFor handler (hd istate) tc <- evaluate (toTypedContent res) @@ -223,8 +223,8 @@ runHandler rhe@RunHandlerEnv {..} handler yreq = withInternalState $ \resState - -- Evaluate the unfortunately-lazy session and headers, -- propagating exceptions into the contents - (finalSession, contents1) <- evalFallback rheShouldCatch contents0 (ghsSession state) - (headers, contents2) <- evalFallback rheShouldCatch contents1 (appEndo (ghsHeaders state) []) + (finalSession, contents1) <- evalFallback rheCatchHandlerExceptions contents0 (ghsSession state) + (headers, contents2) <- evalFallback rheCatchHandlerExceptions contents1 (appEndo (ghsHeaders state) []) contents3 <- (evaluate contents2) `catchAny` (fmap HCError . toErrorHandler) -- Convert the HandlerContents into the final YesodResponse @@ -288,7 +288,7 @@ runFakeHandler fakeSessionMap logger site handler = liftIO $ do , rheLog = messageLoggerSource site $ logger site , rheOnError = errHandler , rheMaxExpires = maxExpires - , rheShouldCatch = catchBehavior site + , rheCatchHandlerExceptions = catchHandlerExceptions site } handler' errHandler err req = do @@ -365,7 +365,7 @@ yesodRunner handler' YesodRunnerEnv {..} route req sendResponse = do , rheLog = log' , rheOnError = safeEh log' , rheMaxExpires = maxExpires - , rheShouldCatch = catchBehavior yreSite + , rheCatchHandlerExceptions = catchHandlerExceptions yreSite } rhe = rheSafe { rheOnError = runHandler rheSafe . errorHandler diff --git a/yesod-core/src/Yesod/Core/Types.hs b/yesod-core/src/Yesod/Core/Types.hs index eb07be47..508f4ad5 100644 --- a/yesod-core/src/Yesod/Core/Types.hs +++ b/yesod-core/src/Yesod/Core/Types.hs @@ -185,8 +185,9 @@ data RunHandlerEnv child site = RunHandlerEnv , rheMaxExpires :: !Text -- | @since 1.6.24.0 - -- should we catch an exception, or rethrow it. - , rheShouldCatch :: !(forall a. IO a -> (SomeException -> IO a) -> IO a) + -- catch function for rendering 500 pages on exceptions. + -- by default this is catch from unliftio (rethrows all async exceptions). + , rheCatchHandlerExceptions :: !(forall a. IO a -> (SomeException -> IO a) -> IO a) } data HandlerData child site = HandlerData diff --git a/yesod-core/test/YesodCoreTest/ErrorHandling/CustomApp.hs b/yesod-core/test/YesodCoreTest/ErrorHandling/CustomApp.hs index 092ee32e..e7e5bde2 100644 --- a/yesod-core/test/YesodCoreTest/ErrorHandling/CustomApp.hs +++ b/yesod-core/test/YesodCoreTest/ErrorHandling/CustomApp.hs @@ -34,7 +34,7 @@ data MyException = MkMyException instance Yesod CustomApp where -- something we couldn't do before, rethrow custom exceptions - catchBehavior _ action handler = + catchHandlerExceptions _ action handler = action `E.catch` \exception -> do case E.fromException exception of Just MkMyException -> E.throwIO MkMyException