处理操作链中的异常(ExceptT)

时间:2015-09-16 02:35:33

标签: haskell exception-handling

我正在尝试使用异常来跳过部分代码。不会被catcheE抓住并恢复正常行为,而是会跳过mapM_链中的所有后续操作。

我查看了this question,看来catchEmaincheckMaybeintercept。 我还检查了mapM_的实现,以确保它符合我的要求,但我不明白Left值如何逃脱dlAsset以影响mapM_的行为。

我从一个版本重构了这个版本,我只是使用一个空字符串作为失败查找的异常标记。在该版本中,checkMaybe只是立即返回Right值并且有效(在""上匹配'捕获')

import Data.HashMap.Strict as HM hiding (map) 
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Char8 as BSC8
import qualified JSONParser as P -- my module

retrieveAssets :: (Text -> Text) -> ExceptT Text IO ()
retrieveAssets withName = withManager $ (lift ((HM.keys . P.assets)
  <$> P.raw) ) >>= mapM_ f
  where
  f = \x -> dlAsset x "0.1246" (withName x)

dlAsset :: Text -> Text -> Text -> ReaderT Manager (ExceptT Text IO) ()
dlAsset name size dest = do
  req <- lift $ (P.assetLookup name size <$> P.raw) >>= checkMaybe
    name >>= parseUrl . unpack -- lookup of a url
  res <- httpLbs req 
  lift $ (liftIO $ BS.writeFile (unpack dest) $ responseBody res)
    `catchE` (\_ -> return ()) -- always a Right value?
    where 
      checkMaybe name a = case a of
        Nothing -> ExceptT $ fmap Left $ do
          BSC8.appendFile "./resources/images/missingFiles.txt" $ 
            BSC8.pack $ (unpack name) ++ "\n"
          putStrLn $ "lookup of " ++ (unpack name) ++ " failed"
          return name
        Just x  -> lift $ pure x

(必须重新格式化,以便在这里变得有些可读)

编辑:我想了解这里实际发生了什么,这可能对我有所帮助,而不仅仅是知道哪部分代码是错误的。

1 个答案:

答案 0 :(得分:1)

问题是,您对catchE的来电仅涵盖dlAsset的最后一行。它需要移动到do-notation缩进级别的左侧以覆盖所有的符号。