{-# LANGUAGE OverloadedStrings, DataKinds#-} module Requester(request) where import qualified Network.Wreq as N import Network.HTTP.Client (HttpException) import qualified Control.Exception as E import Control.Lens.Getter ((^.)) import qualified Data.ByteString.Lazy as LBS import Monad url :: String url = "https://md.darmstadt.ccc.de/mathechor-probenplanung/download" eitherToFail :: (Show a, MonadFail m) => Either a b -> m b eitherToFail (Right a) = return a eitherToFail (Left b) = fail $ show b request :: (MonadIO m, MonadFail m) => m LBS.ByteString request = do -- catch might seem to be more convenient instead of catch. But the handler in catch forces -- IO and not MonadIO, so we can't call fail. We use try to escape so we can escape IO first -- and then handle the error (with fail in scope) responseWithError <- liftIO (E.try (N.get url) :: IO (Either HttpException (N.Response LBS.ByteString))) response <- eitherToFail responseWithError return $ response ^. N.responseBody