如何使用http-enumerator处理异常

Nei*_*eil 2 haskell

Haskell新手在这里.我正在尝试使用http-enumerator通过HTTP上的XML查询服务.我能够连接并发送xml格式的请求,并接收xml格式的响应.

查询成功后,服务器将发回一个响应

我正在努力的是处理FAULT文档中指出的异常的正确方法.我正在尝试使用Either,但没有成功.

我在下面编写的ghci:

import Network.HTTP.Enumerator 
import Network.HTTP.Types

import qualified Data.ByteString.Lazy as L 
import Data.ByteString.UTF8

import Text.XML.Light

hostname = "https://server..."

doPost username password token = do

    let q = QName "SYSTEM" Nothing Nothing

    let attribs = [Attr {attrKey = QName "user" Nothing Nothing, attrVal = username},
                   Attr {attrKey = QName "password" Nothing Nothing, attrVal = password},
                   Attr {attrKey = QName "token" Nothing Nothing, attrVal = token}]

    let doc = Element {elName=q, elAttribs=attribs, elContent= [], elLine=Nothing}

    req0 <- parseUrl hostname 

    let req = req0 { method = methodPost 
                  , requestHeaders = [("Content-Type", "text/xml")]   
                  , requestBody = RequestBodyBS $ fromString $ showTopElement doc
                  } 

    res <- withManager $ httpLbs req 

    let status = Network.HTTP.Enumerator.statusCode res
    let content = responseBody res

    -- this is where I would check for different fault codes using a case statement
    if content == "<FAULT/>"
        then Left "error"
        else Right content
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试在ghci中运行它时,我得到以下内容:

*Main> doPost "user" "password" ""

<interactive>:1:1:
    No instances for (Control.Failure.Failure
                        HttpException (Either a0),
                      Control.Monad.IO.Control.MonadControlIO (Either a0))
      arising from a use of `doPost'
    Possible fix:
      add instance declarations for
      (Control.Failure.Failure HttpException (Either a0),
       Control.Monad.IO.Control.MonadControlIO (Either a0))
    In the expression: doPost "user" "password" ""
    In an equation for `it': it = doPost "user" "password" ""
Run Code Online (Sandbox Code Playgroud)

在这种情况下处理异常的最佳方法是什么?

提前致谢.尼尔

Mic*_*man 6

你需要在最后一个if之前放一个"return $".parseUrl需要在monad中运行,monad是Failure HttpExceptionIO或Maybe 的实例.withManager需要一个monad,这是一个例子MonadControlIO,如IO.

目前,您if最终强制整个do-block在Either Stringmonad中运行,这就是为什么你得到"无实例"的例外.如果你添加一个回报,你的最终结果将是这样的IO (Either String XML).