2015-09-16 2 views
0

Я пытаюсь использовать исключение, чтобы пропустить части кода здесь. Вместо того, чтобы поймать catcheE и возобновить нормальное поведение, все следующие действия в цепочке mapM_ пропущены.Обработка исключений (ExceptT) в цепочке действий

Я посмотрел на this question и, кажется, что catchE ~ main и checkMaybe ~ intercept. Я также проверил реализацию mapM_, чтобы убедиться, что он делает то, что я хочу, но я не понимаю, как левое значение может уйти 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 

(пришлось переформатировать, чтобы стать несколько читаемым здесь)

редактировать: я хотел бы понять, что на самом деле происходит здесь, что, вероятно, поможет мне больше, чем знать, какая часть кода неверна.

+0

Что вы говорите об этом «главном» и «перехвате»? Что вы на самом деле пытаетесь сделать? – dfeuer

+0

main и intercept - это то, что связанный ответ использует в своем примере – CryptoCamel

ответ

1

Проблема заключается в том, что ваш звонок catchE охватывает только последнюю строку dlAsset. Он должен быть перемещен влево от уровня отступов do-notation для охвата всех обозначений.