Haskell `wreq`Get/Post与异常处理

Haskell `wreq`Get/Post与异常处理,haskell,Haskell,我正在使用wreq进行一些http调用,希望捕获任何异常并返回other类型。我尝试了类似的方法,但无法找出如何操纵调用,以便它进行类型检查 -- exhaustive pattern match omitted here safeGetUrl :: URL -> Maybe Login -> Maybe Password -> IO (Either String (Response LBS.ByteString)) safeGetUrl url (Just login)

我正在使用
wreq
进行一些http调用,希望捕获任何异常并返回
other
类型。我尝试了类似的方法,但无法找出如何操纵调用,以便它进行类型检查

 -- exhaustive pattern match omitted here
 safeGetUrl :: URL -> Maybe Login -> Maybe Password -> IO (Either String (Response LBS.ByteString))
 safeGetUrl url (Just login) (Just pass) = do
     let def  = defaults
         opts = def & auth ?~ basicAuth (BS.pack login) (BS.pack pass)
     r <- getWith opts url  `E.catch` handler
     return $ Right r

   where
     handler :: HttpException -> Either String (Response LBS.ByteString)
     handler (StatusCodeException s _ _) = do
          return $ Left $ LBS.unpack (s ^. statusMessage)

是否有方法捕获此异常并返回
IO类型

您的问题是句柄的一侧返回一个未包装的响应(no
other
),而另一侧返回一个
other
包装的异常。然后尝试将响应包装在
中,您确实需要这样做,但它只是放在了错误的位置。您只需切换包装位置即可解决此问题

safeGetUrl :: URL -> Maybe Login -> Maybe Password -> IO (Either String (Response LBS.ByteString))
 safeGetUrl url (Just login) (Just pass) = do
     let def  = defaults
         opts = def & auth ?~ basicAuth (BS.pack login) (BS.pack pass)
     (Right <$> getWith opts url) `E.catch` handler

   where
     handler :: HttpException -> IO (Either String (Response LBS.ByteString))
     handler (StatusCodeException s _ _) = do
          return $ Left $ LBS.unpack (s ^. statusMessage)

自从@jozefg answer之后,API发生了一点变化,答案不再编译

以下是编译以下内容的更新版本:

导入限定控件。异常为E
进口管制.镜头
将符合条件的Data.ByteString.Char8导入为BSC
将限定数据.ByteString.Lazy导入为LBS
导入Network.HTTP.Client
导入网络。Wreq为NW
类型URL=String
类型Login=String
键入密码=字符串
safeGetUrl::
统一资源定位地址
->也许登录
->也许是密码
->IO(任一字符串(响应LBS.ByteString))
safeGetUrl url(仅登录)(仅通过)=执行
设def=默认值
opts=def&auth?~basicAuth(BSC.pack登录)(BSC.pack密码)
(右getWith opts url)`E.catch`handler
哪里
handler::HttpException->IO(任一字符串(响应LBS.ByteString))
处理程序(HttpExceptionRequest(StatusCodeException r))=
返回$Left$BSC.unpack(r^.NW.responseStatus.statusMessage)

谢谢。我当时正试着用
抬起
getWith
,不知怎么搞不懂怎么做。我仍然处于Haskell的初级阶段,因此没有立即看到如何使用
将响应封装在其中。关于
BSC
LBS
。。。这是我的疏忽——谢谢你指出这一点。
safeGetUrl :: URL -> Maybe Login -> Maybe Password -> IO (Either String (Response LBS.ByteString))
 safeGetUrl url (Just login) (Just pass) = do
     let def  = defaults
         opts = def & auth ?~ basicAuth (BS.pack login) (BS.pack pass)
     (Right <$> getWith opts url) `E.catch` handler

   where
     handler :: HttpException -> IO (Either String (Response LBS.ByteString))
     handler (StatusCodeException s _ _) = do
          return $ Left $ LBS.unpack (s ^. statusMessage)
import Control.Lens
import Network.Wreq
import Network.HTTP.Client
import qualified Control.Exception as E
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as LBS

type URL = String
type Login = String
type Password = String

safeGetUrl :: URL
           -> Maybe Login
           -> Maybe Password
           -> IO (Either String (Response LBS.ByteString))
safeGetUrl url (Just login) (Just pass) = do
  let def  = defaults
      opts = def & auth ?~ basicAuth (BSC.pack login) (BSC.pack pass)
  (Right <$> getWith opts url)  `E.catch` handler
  where
    handler :: HttpException -> IO (Either String (Response LBS.ByteString))
    handler (StatusCodeException s _ _) = do
      return $ Left $ BSC.unpack (s ^. statusMessage)