gpt4 book ai didi

haskell - 在 Happstack 请求处理程序中捕获程序错误

转载 作者:行者123 更新时间:2023-12-02 17:42:04 25 4
gpt4 key购买 nike

我对 Haskell 有点菜鸟,所以我不完全确定这是 Happstack 问题还是一般 Haskell 问题。

这是我遇到的困难的一个例子。这段代码“理论上”渲染了一些内容,但实际上抛出了一个错误:

throwsError :: String
throwsError = fromJust Nothing

-- no error page
main :: IO ()
main = do
simpleHTTP nullConf $ do
decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096)
ok $ toResponse throwsError

此错误不会使整个程序崩溃。幸运的是,Happstack 可以捕获处理请求时抛出的任何错误,就像 Web 服务器应该做的那样。但是,不幸的是它不会向用户显示任何类型的错误页面。它以状态代码 200 和空内容进行响应。

现在,如果我只是先输出错误字符串:

-- yes error page
main :: IO ()
main = do
simpleHTTP nullConf $ do
decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096)
lift $ putStrLn throwsError -- added this line
ok $ toResponse throwsError

Happstack 返回状态 500 并显示错误页面。为什么 Happstack 会这样?

ServerPart monad 实现了 MonadThrow,所以我尝试导入 Control.Monad.Catch (handle) 并编写这个,但它没有'没有做我期望的事;它再次返回 200,没有内容:

showErrorPage :: SomeException -> ServerPart Response
showErrorPage _ = internalServerError $ toResponse "Error"

-- also no error page
main :: IO ()
main = do
simpleHTTP nullConf $ handle showErrorPage $ do
decodeBody (defaultBodyPolicy "/tmp/" 4096 4096 4096)
ok $ toResponse throwsError

如果不清楚,我想处理抛出的所有错误,以便我可以记录它们并显示自定义错误页面。 (当然,记录和显示错误页面时引发的错误除外)。指导将不胜感激。

最佳答案

顺便说一句,我找到了答案。基本上它与惰性评估有关 - Response 对象仅评估为 WHNF,直到 Happstack 内部开始将数据流式传输到响应正文中,此时更改状态代码为时已晚。 200 到 500。

如果响应是视频流,这是正确的行为,因为在发送 HTTP 响应之前严格评估响应以确保它不包含任何 未定义 值在这种情况下会很麻烦。然而,对于已知的小响应来说,进行深入、严格的评估以消除任何底值的可能性显然是不方便的。此外,HTTP 客户端(主要是浏览器)隐式地假设 200 响应代码意味着请求成功 - 并且仅在特定情况下(例如流媒体视频)200 响应无论如何都是“不可信的”,并且使用该代码的代码HTTP 响应会更深入地研究它,以确保在处理并将其显示给最终用户之前它格式正确且格式正确 - 实际上正如我的问题中所见,浏览器显示一个空页面并且网络选项卡显示 200 没有任何内容,尽管有很多内部服务器错误。

Here是我针对 Happstack 的拉取请求,它只是向 Response 对象添加一些类型类,以便可以在将其返回到 ServerPart monad 之前对其进行深入、严格的评估。那个特定的 PR 有一段麻烦的历史(它曾经做过一些范围更大的事情),所以我可能会关闭它并打开一个新的。如果是这样,则应将该链接标记为已关闭,并提供指向新链接的链接。

关于haskell - 在 Happstack 请求处理程序中捕获程序错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47153651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com