【问题标题】:Elm read HTTP response body for non-200 responseElm 读取非 200 响应的 HTTP 响应正文
【发布时间】:2016-05-03 10:35:17
【问题描述】:

如何读取非 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 有效负载的形式响应请求的错误之处。请帮我从下面的任务 x a 中检索到 ServerResult。

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

【问题讨论】:

    标签: elm


    【解决方案1】:

    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 视为成功:

    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
    

    同样,代码 sn-p 几乎完全是复制和粘贴的,除了 400 状态检查。像这样复制和粘贴通常是最后的手段,但由于图书馆的限制,这似乎是您目前唯一的选择之一。

    【讨论】:

    • 感谢您的建议。 :) 我会试试这个。我还创建了一个问题,看看这是否可以在库级别修复。
    猜你喜欢
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多