如何使用异常处理在Haskell中编写“ retryForever”函数?

时间:2019-08-23 21:19:32

标签: haskell exception classy-prelude

我想创建一个可以从合理的错误中恢复的函数,然后重试。当然,程序的其他部分还包含对错误的有意义的处理-这是使事情保持正常运转的最后努力。所以我写了这个:

{
"book": "Robin hood", 
"photos":  [ "https://picsum.photos/id/1001/5616/3744"],
 }

然后,我将主要的IO操作包装在retryForever prog = catchAny prog progRetry where progRetry :: SomeException -> m a progRetry ex = do putStrLn $ pack $ show ex threadDelay 4000 prog 中:

retryForever

在程序的另一部分(可能是不同的绿色线程)中,我用以下方法进行测试:

main :: IO ()
main = retryForever $ do
  logger <- newLogger
  -- ...

结果:

error "this is a TEST ERROR"

(程序死掉而不是继续执行)

请注意,在某些情况下,例如,我正在使用classy-prelude。 : this is a TEST ERROR CallStack (from HasCallStack): error, called at XXXX 不在那里处理异步异常,这很可能是这里的问题。

1 个答案:

答案 0 :(得分:5)

当程序失败时,您应该再次运行程序prog,但是将其包装在retryForever中,这样如果再次失败,则可以继续尝试:

import Control.Monad.Catch(catchAll)

retryForever :: IO a -> IO a
retryForever prog = catchAll prog retry
  where retry ex = do
      putStrLn $ pack $ show ex
      threadDelay 4000
      retryForever prog