gpt4 book ai didi

haskell - 如何在不终止网站的情况下捕获 Yesod 中的异常?

转载 作者:行者123 更新时间:2023-12-02 16:05:55 24 4
gpt4 key购买 nike

我是 Yesod 和 Haskell 的新手,所以请耐心等待,但我有一个程序可以接受文件、计算单词数并在新的 Yesod 网页上显示结果。我需要一种更优雅地捕获异常的方法。例如,如果它在隐藏文件上运行以下函数:

wordCount :: String -> String -> String

wordCount ('.' : _) _ = error "Cannot count hidden files."
wordCount name contents = "<p>There are <b>" ++ show (length $ words contents) ++ "</b> words in your file <i>" ++ name ++ "</i>.</p>"

我想显示该错误消息,然后显示供用户提交新文件的表单。现在它只是转到一个页面,显示“加载页面时与服务器的连接已重置。”

我认为 Yesod 有自己的一套 catch 函数,我可能必须隐藏它们才能编写自己的函数,但我不确定它们在哪里,并且在任何文档中都找不到对它们的任何引用。我不希望网站在用户输入错误文件时崩溃。

任何帮助将不胜感激。

编辑:感谢您的建议。我意识到以这种方式抛出错误并不是处理错误的最佳方法,但问题实际上是我正在使用现有的 Haskell 代码,这些代码通常从终端运行,而不是 Yesod 站点。我使用了 wordcount 作为一个小例子,但实际上它是数十个文件,具有数十个函数和分散的错误抛出。希望我能够捕捉到这些,而不必完全修改现有代码中的每个函数。如果有人对如何在 Yesod 中捕获异常有任何建议,我将非常感激。

最佳答案

正如 dflemstr 所说,不要将 error 用于此类可恢复错误。错误机制与undefined类似——它表示完全灾难性的错误,例如尚未编写的函数或无限循环。对于您希望永远不会遇到坏情况的部分函数来说,这很好,但对于预期且必须处理的错误来说,它并不是最佳选择。此外,类型系统不会反射(reflect)您对错误的使用,因此函数的使用者无法知道捕获错误。

相反,您应该使用像 MaybeEither 这样的类型来表示这样的错误。例如,您可以将此函数重写为:

wordCount :: String -> String -> Maybe String
wordCount ('.' : _) _ = Nothing
wordCount name contents = Just $ "<p>There are <b>" ++ show (length $ words contents) ++ "</b> words in your file <i>" ++ name ++ "</i>.</p>"

现在,您不再返回 String,而是返回 Maybe String。这是一种可以是 NothingJust String 的类型。 Nothing 代表失败——也就是说,函数由于输入无效而失败。 Just 代表成功。

接下来,要“捕获”错误,您只需进行模式匹配即可:

case wordCount fileName contents of
Just res -> res
Nothing -> "Cannot count hidden files!"

Data.Maybe中还有一些方便的功能使您的代码在常见情况下更加整洁。

另一个选项是Either 类型。在 Maybe 类型中,Nothing 构造函数不携带任何附加信息。您只知道该功能失败了。 Either 的行为方式相同,除了“失败”情况确实携带任意附加信息。 “失败”情况称为“左”,“成功”情况称为“右”。该类型也有两个参数:错误信息的类型和结果的类型。它看起来像这样:

wordCount :: String -> String -> Either String String
wordCount ('.' : _) _ = Left "You cannot count a hidden file!"
wordCount name contents = Right $ "<p>There are <b>" ++ show (length $ words contents) ++ "</b> words in your file <i>" ++ name ++ "</i>.</p>"

然后您可以像 Maybe 一样处理结果。在这种情况下,我认为 Maybe 更好,因为只有一种方法会导致函数失败。如果存在多种可能的错误情况,Either 会是更好的选择。

关于haskell - 如何在不终止网站的情况下捕获 Yesod 中的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11618760/

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