choonkeat / elm-ext-http / Ext.Http

This module extends the Http module with better error handling and more information in the success case.


type Error a
    = BadUrl String
    | Timeout
    | NetworkError
    | BadStatus Http.Metadata a
    | BadJson Http.Metadata a Json.Decode.Error

Use Ext.Http.Error instead of Http.Error to get more information about the error.


type alias TaskInput x a =
{ method : String
, headers : List Http.Header
, url : String
, body : Http.Body
, resolver : Http.Resolver x a
, timeout : Maybe Basics.Float 
}

Named type alias for the Http.task parameter

errorString : Error String -> String

Convenience function to convert an Ext.Http.Error to a String.


type alias Data a =
{ meta : Http.Metadata, data : a }

When http succeeds, you get a Data record with both the Http.Metadata and the data that was decoded from the response.

Http.task request
    |> Task.andThen
        (\{ meta, data } ->
            -- do something with meta and/or data
            -- like checking the status code
        )

identityResolver : Http.Response a -> Result (Error a) (Data a)

Useful for non-json payloads like Bytes or String

A resolver that does not process the response at all. It just returns the response as-is, but with Http.Metadata included. And with error type as Ext.Http.Error instead of Http.Error.

jsonResolver : Json.Decode.Decoder a -> Http.Response String -> Result (Error String) (Data a)

Resolver for Http.task that includes proper details in both the error case and metadata in the success case.

Usually metadata is not needed in the success case, just add Task.map .data to your existing code

```diff
 Http.task
     { method = "GET"
     , headers = []
     , url = "https://example.com"
     , body = Http.emptyBody
-    , resolver = Http.stringResolver (otherJsonResolver myDecoder)
+    , resolver = Http.stringResolver (Ext.Http.jsonResolver myDecoder)
     , timeout = Nothing
     }
+    |> Task.map .data
```

But when you need it, having the metadata available is very useful.

```diff
 Http.task
     { method = "GET"
     , headers = []
     , url = "https://example.com"
     , body = Http.emptyBody
     , resolver = Http.stringResolver (Ext.Http.jsonResolver myDecoder)
     , timeout = Nothing
     }
+    |> Task.map (Debug.log "{ meta, data }")
     |> Task.map .data
```