简体   繁体   English

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

[英]How to write a “retryForever” function in Haskell using exception handling?

I'd like to create a function that can recover from as many errors as is reasonable, and try again. 我想创建一个可以从合理的错误中恢复的函数,然后再试一次。 Of course, meaningful handling of errors is covered in other parts of the program - this is a last ditch effort to keep things running. 当然,程序的其他部分也包含有意义的错误处理 - 这是保持运行的最后努力。 So I wrote this: 所以我写了这个:

retryForever prog = catchAny prog progRetry
  where
    progRetry :: SomeException -> m a
    progRetry ex = do
      putStrLn $ pack $ show ex
      threadDelay 4000
      prog

Then I wrap my main IO action in retryForever : 然后我将我的主IO动作包装在retryForever

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

In another part of my program (likely a different green thread), I test this with: 在我的程序的另一部分(可能是一个不同的绿色线程),我用以下方法测试:

error "this is a TEST ERROR"

Resulting in: 导致:

: this is a TEST ERROR
CallStack (from HasCallStack):
  error, called at XXXX

(and the program dies instead of continuing on) (程序会死而不是继续)

Note that I'm using classy-prelude, for the cases where that may matter, eg catchAny doesn't handle asynchronous exceptions in there, which may well be the issue here. 请注意,我正在使用classy-prelude,对于可能很重要的情况,例如catchAny不会处理那里的异步异常,这可能是这里的问题。

When the program failed, you should run the program prog again, but wrapped in retryForever such that if it fails again, you thus keep trying: 当程序失败时,你应该再次运行程序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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM