Elm读取非响应的HTTP响应正文

时间:2016-01-26 18:23:25

标签: elm

如何读取非200 HTTP状态的HTTP响应正文

getJson : String -> String -> Effects Action
getJson url credentials =
  Http.send Http.defaultSettings
    { verb = "GET"
    , headers = [("Authorization", "Basic " ++ credentials)]
    , url = url
    , body = Http.empty
    }
    |> Http.fromJson decodeAccessToken
    |> Task.toResult
    |> Task.map UpdateAccessTokenFromServer
    |> Effects.task

以上提升了

的错误
Task.toResult : Task Http.Error a -> Task x (Result Http.Error a)

其值变为

(BadResponse 400(“错误请求”))

我的服务器响应请求的错误作为响应正文中的JSON有效负载。请帮我从Task x a检索到下面的ServerResult。

type alias ServerResult = { status : Int, message : String }

1 个答案:

答案 0 :(得分:3)

Http package (v3.0.0)没有公开一种简单的方法来处理200到300范围之外的HTTP代码作为非错误响应。查看源代码the handleResponse function is looking between the hardcoded 200 to 300 range

但是,通过从Http包源代码中进行一些复制和粘贴,您可以创建一个自定义函数来替换Http.fromJson,以便处理正常“成功”范围之外的HTTP状态代码。

以下是您需要复制和粘贴以创建自定义myFromJson函数的最低限度示例,该函数与Http包的作用相同,但事实上它还将400视为成功:< / p>

myFromJson : Json.Decoder a -> Task Http.RawError Http.Response -> Task Http.Error a
myFromJson decoder response =
  let decode str =
        case Json.decodeString decoder str of
          Ok v -> Task.succeed v
          Err msg -> Task.fail (Http.UnexpectedPayload msg)
  in
      Task.mapError promoteError response
        `Task.andThen` myHandleResponse decode


myHandleResponse : (String -> Task Http.Error a) -> Http.Response -> Task Http.Error a
myHandleResponse handle response =
  if (200 <= response.status && response.status < 300) || response.status == 400 then

      case response.value of
        Http.Text str ->
            handle str

        _ ->
            Task.fail (Http.UnexpectedPayload "Response body is a blob, expecting a string.")

  else

      Task.fail (Http.BadResponse response.status response.statusText)

-- copied verbatim from Http package because it was not exposed
promoteError : Http.RawError -> Http.Error
promoteError rawError =
  case rawError of
    Http.RawTimeout -> Http.Timeout
    Http.RawNetworkError -> Http.NetworkError

同样,除了400状态检查之外,该代码片段几乎完全被复制和粘贴。像这样复制和粘贴通常是最后的手段,但由于库的限制,它似乎是你目前唯一的选择之一。