如何使用异常处理在 Haskell 中编写 "retryForever" 函数?
How to write a "retryForever" function in Haskell using exception handling?
我想创建一个可以从尽可能多的错误中恢复的函数,然后再试一次。当然,有意义的错误处理包含在程序的其他部分 - 这是保留内容的最后努力 运行。所以我写了这个:
retryForever prog = catchAny prog progRetry
where
progRetry :: SomeException -> m a
progRetry ex = do
putStrLn $ pack $ show ex
threadDelay 4000
prog
然后我将我的主要 IO 操作包装在 retryForever
:
main :: IO ()
main = retryForever $ do
logger <- newLogger
-- ...
在我程序的另一部分(可能是不同的绿色线程)中,我使用以下方法进行测试:
error "this is a TEST ERROR"
导致:
: this is a TEST ERROR
CallStack (from HasCallStack):
error, called at XXXX
(程序终止而不是继续)
请注意,我使用的是 classy-prelude,用于可能重要的情况,例如catchAny
那里不处理异步异常,这很可能是这里的问题。
当程序失败时,您应该 运行 程序再次 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
我想创建一个可以从尽可能多的错误中恢复的函数,然后再试一次。当然,有意义的错误处理包含在程序的其他部分 - 这是保留内容的最后努力 运行。所以我写了这个:
retryForever prog = catchAny prog progRetry
where
progRetry :: SomeException -> m a
progRetry ex = do
putStrLn $ pack $ show ex
threadDelay 4000
prog
然后我将我的主要 IO 操作包装在 retryForever
:
main :: IO ()
main = retryForever $ do
logger <- newLogger
-- ...
在我程序的另一部分(可能是不同的绿色线程)中,我使用以下方法进行测试:
error "this is a TEST ERROR"
导致:
: this is a TEST ERROR
CallStack (from HasCallStack):
error, called at XXXX
(程序终止而不是继续)
请注意,我使用的是 classy-prelude,用于可能重要的情况,例如catchAny
那里不处理异步异常,这很可能是这里的问题。
当程序失败时,您应该 运行 程序再次 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