我正在编写一个查询REST端点以获取某些数据的函数,比如queryServer
:
queryServer :: (MonadIO m, MonadError Message m) => URL -> m String
我想使用MonadError
中的Control.Monad.Except
的原因是我希望这个monad具有短路行为。例如,它可以如下使用:
queryServers :: (MonadIO m, MonadError Message m) => m (String, String)
queryServers = do
res0 <- queryServer "server0"
res1 <- queryServer "server1"
return (res0, res1)
通过这种方式,我不必担心捕获queryServer
处发生的异常,并且一旦遇到错误,该函数就会失败。
我对这种方法的问题(可能还有其他我不知道的)是我必须使用一些样板来捕获IO异常并用throwError
重新抛出它们:
queryServer url = do
result <- liftIO $ try (fetchSomething url)
case result of
Left (e :: IOException) -> throwError "error when fetching"
Right sth -> return sth
fetchSomething :: URL -> IO String
fetchSomething = undefined
我已经看到了几个关于在Haskell中正确使用异常的问题,例如this one,但是没有一个问题涉及MonadError
。
在`MonadError?
中处理IO异常的正确方法是什么?