如何读取非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 }
答案 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状态检查之外,该代码片段几乎完全被复制和粘贴。像这样复制和粘贴通常是最后的手段,但由于库的限制,它似乎是你目前唯一的选择之一。