使用 HTTP 管道时如何干净地处理所有可能的错误?
Posted
技术标签:
【中文标题】使用 HTTP 管道时如何干净地处理所有可能的错误?【英文标题】:How to handle all possible errors cleanly when using HTTP conduit? 【发布时间】:2013-08-10 17:20:33 【问题描述】:我有一些看起来像这样的代码:
retryOnTimeout :: IO a -> IO a
retryOnTimeout action = catch action $ \ResponseTimeout ->
do putStrLn "Timed out. Trying again."
threadDelay 5000000
action
问题是 HttpException 的其他构造函数还有很多,我一般会继续尝试,不管错误到底是什么。现在,如果我将ResponseTimeout
替换为_
,则会出现编译错误,因为它无法推断出异常的类型。
我也不想为异常处理程序提供类型签名。
我知道这不是 太多 重复,但是为 _
添加一个案例感觉不对,因为这就像在说:如果异常是 ResponseTimeout 则执行 x,但如果异常是其他任何东西 做同样的事情。有没有一种使用通配符的简洁方法,但仍然让编译器知道它是哪种类型?
【问题讨论】:
catch action $ \ (_ :: HttpException) -> do ...
怎么样?可能需要打开ScopedTypeVariables
才能编译。
啊啊啊! ScopedType 变量! GHC 甚至建议这样做,但我认为这是错误的,因为我以前从未见过扩展的确切用法。请添加为答案,以便我接受,谢谢!
您也可以编写 \~ResponseTimeout ->
来绑定类型而不进行任何实际匹配,因为 ~
是一种惰性模式。但是,ScopedTypeVariables
是一个更好的解决方案。
【参考方案1】:
如果您不关心异常值,使用 _
完全可以,但您需要使用 ScopedTypeVariables
或 let 子句来指定您想要的类型。
-# LANGUAGE ScopedTypeVariables #-
retryOnTimeout :: IO a -> IO a
retryOnTimeout action = catch action $ \ (_ :: HttpException) -> do
putStrLn "Timed out. Trying again."
threadDelay 5000000
action
【讨论】:
以上是关于使用 HTTP 管道时如何干净地处理所有可能的错误?的主要内容,如果未能解决你的问题,请参考以下文章
如何最好地处理 Neuraxle 管道中的错误和/或丢失数据?