@@ -396,9 +396,11 @@ serveConnection conn ii1 origAddr transport settings app = do
396396
397397 sendErrorResponse req istatus e = do
398398 status <- readIORef istatus
399− when (shouldSendErrorResponse e && status) $ do
400− let ii = toInternalInfo ii1 0 -- dummy
401− void $ sendResponse settings conn ii req defaultIndexRequestHeader (return S.empty) (errorResponse e)
399+ if (shouldSendErrorResponse e && status)
400+ then do
401+ let ii = toInternalInfo ii1 0 -- dummy
402+ sendResponse settings conn ii req defaultIndexRequestHeader (return S.empty) (errorResponse e)
403+ else return False
402404
403405 dummyreq addr = defaultRequest { remoteHost = addr }
404406
@@ -409,22 +411,9 @@ serveConnection conn ii1 origAddr transport settings app = do
409411 let req = req' { isSecure = isTransportSecure transport }
410412 keepAlive <- processRequest istatus src req mremainingRef idxhdr nextBodyFlush ii
411413 `E.catch` \e -> do
412− -- Attempt to unwrap exception and use it to determine
413− -- safety of keeping exception alive
414− case fromException e of
415− Nothing -> do
416− -- Call the user-supplied exception handlers, passing the request.
417− sendErrorResponse req istatus e
418− settingsOnException settings (Just req) e
419− -- Don't throw the error again to prevent calling settingsOnException twice.
420− let (isPersist, _) = infoFromRequest req idxhdr
421− return isPersist
422− Just (ExceptionInsideResponseBody e') -> do
423− -- Call the user-supplied exception handlers, passing the request.
424− sendErrorResponse req istatus e'
425− settingsOnException settings (Just req) e'
426− -- Don't throw the error again to prevent calling settingsOnException twice.
427− return False
414+ settingsOnException settings (Just req) e
415+ -- Don't throw the error again to prevent calling settingsOnException twice.
416+ return False
428417
429418 -- When doing a keep-alive connection, the other side may just
430419 -- close the connection. We don't want to treat that as an
@@ -444,7 +433,7 @@ serveConnection conn ii1 origAddr transport settings app = do
444433 -- creating the request, we need to make sure that we don't get
445434 -- an async exception before calling the ResponseSource.
446435 keepAliveRef <- newIORef $ error "keepAliveRef not filled"
447− _ <- app req $ \res -> do
436+ r <- E.try $ app req $ \res -> do
448437 T.resume th
449438 -- FIXME consider forcing evaluation of the res here to
450439 -- send more meaningful error messages to the user.
@@ -453,6 +442,15 @@ serveConnection conn ii1 origAddr transport settings app = do
453442 keepAlive <- sendResponse settings conn ii req idxhdr (readSource src) res
454443 writeIORef keepAliveRef keepAlive
455444 return ResponseReceived
445+ case r of
446+ Right ResponseReceived -> return ()
447+ Left e@(SomeException _)
448+ | Just (ExceptionInsideResponseBody e') <- fromException e -> throwIO e'
449+ | otherwise -> do
450+ keepAlive <- sendErrorResponse req istatus e
451+ settingsOnException settings (Just req) e
452+ writeIORef keepAliveRef keepAlive
453+
456454 keepAlive <- readIORef keepAliveRef
457455
458456 -- We just send a Response and it takes a time to