Elm 0.19: Как получить тело запроса при получении BadStatus с elm / http 2.0.0 - PullRequest
0 голосов
/ 26 января 2019

вяз / http 1.0.0 определяется Http.Error как

type Error
    = BadUrl String
    | Timeout
    | NetworkError
    | BadStatus (Response String)
    | BadPayload String (Response String)

, но 2.0.0 изменил его на

type Error
    = BadUrl String
    | Timeout
    | NetworkError
    | BadStatus Int
    | BadBody String

При получении BadStatus Я не могу получить тело запроса, только код состояния. В документах Эван предлагает решение для этого, но я не понимаю, как заставить его работать.

Если мы определили нашу собственную expectJson похожую на

expectJson : (Result Http.Error a -> msg) -> D.Decoder a -> Expect msg
expectJson toMsg decoder =
  expectStringResponse toMsg <|
    \response ->
      case response of
        Http.BadStatus_ metadata body ->
          Err (Http.BadStatus metadata.statusCode)
        ...

Тогда у нас есть доступ к метаданным и телу, но как мне их использовать? Должен ли я определить свой собственный myBadStatus и вернуть его вместо этого?

Http.BadStatus_ metadata body ->
  Err (myBadStatus metadata.statusCode body)

Будет ли это работать?

Мне нужно преобразовать следующий код:

myErrorMessage : Http.Error -> String
myErrorMessage error =
    case error of
        Http.BadStatus response ->
            case Decode.decodeString myErrorDecoder response.body of
                Ok err ->
                    err.message
                Err e ->
                    "Failed to parse JSON response."
        ...

Спасибо.

1 Ответ

0 голосов
/ 01 февраля 2019

Изменить 22/4/2019: Я обновил этот ответ для версии 2.0+ http-extras, в которой есть некоторые изменения API. Спасибо Беренд де Бур за то, что указал на это!

Ответ ниже дает решение с использованием пакета, который я написал (согласно запросу), но вам не нужно использовать пакет! Я написал всю статью о том, как извлечь подробную информацию из HTTP-ответа, она включает в себя несколько примеров Элли, которые не требуют пакета, а также пример, который использует пакет.


Как упоминал Франческо, я создал пакет именно для этой цели, используя похожий подход, описанный в вопросе: https://package.elm -lang.org / packages / jzxhuang / http-extras / latest / .

В частности, модуль для использования Http.Detailed. Он определяет тип ошибки, который сохраняет исходное тело при ошибке:

type Error body
    = BadUrl String
    | Timeout
    | NetworkError
    | BadStatus Metadata body Int
    | BadBody Metadata body String

Сделать запрос так:

type Msg
    = MyAPIResponse (Result (Http.Detailed.Error String) ( Http.Metadata, String ))

sendRequest : Cmd Msg
sendRequest =
    Http.get
        { url = "/myapi"
        , expect = Http.Detailed.expectString MyAPIResponse

В вашем обновлении обработайте результат, включая декодирование тела, когда оно имеет статус BadStatus:

update msg model =
    case msg of
        MyAPIResponse httpResponse ->
            case httpResponse of
                Ok ( metadata, respBody ) ->
                    -- Do something with the metadata if you need! i.e. access a header

                Err error ->
                    case error of
                        Http.Detailed.BadStatus metadata body statusCode ->
                            -- Try to decode the body the body here...

                        ...

        ...

Спасибо, Франциско, за то, что обратились ко мне по этому поводу, надеюсь, этот ответ поможет всем, кто сталкивается с той же проблемой, что и ОП.

...