TheTeaMan
TheTeaMan

Reputation: 2513

Error handling and Signals

I have an Elm app that needs to communicate to a server using Http on Elm Platform 0.14.1. The app needs to validate that its requests are valid before sending them to the server.

Currently I am using a function makeRequest to take some data from the model and make an Http.Request based on it with invalid requests returning Http.get "". This is a hack and I want to replace it with proper error handling.

The types of the functions I have are:

makeRequest : List String -> Request String
Http.send : Signal (Request a) -> Signal (Response String)

I want to wrap the result of makeRequest in Result so that I can handle the errors properly. I also want to wrap Http.send so that it propagate errors.

Ideally I would like to end up with:

newMakeRequest : List String -> Result String (Request String)
newSend : Signal (Result String (Request a)) -> Signal (Result String (Response String))

Constructing newMakeRequest is trivial. But I am not sure how to approach newSend or if it is even possible.

Upvotes: 2

Views: 549

Answers (1)

Apanatshka
Apanatshka

Reputation: 5958

Ok, so all you need is the newSend right? That's possible:

newSend : Result x (Reponse a) -> Signal (Result x (Request a)) -> Signal (Result x (Response a))
newSend defaultResp s =
  let reqs =
        s |> Signal.keepIf isOk (Ok (Http.get ""))
          |> Signal.map unpackOk
      errs =
        s |> Signal.dropIf isOk defaultResp
          |> Signal.map errIdentity
  in Signal.merge errs (Signal.map Ok (Http.send reqs))

-- Change the type of an Err Result. 
errIdentity : Result x a -> Result x b
errIdentity =
  Result.map (Debug.crash "errIdentity: Don't call this function on an Ok!")

unpackOk : Result x a -> a
unpackOk =
  case res of
    Ok  a -> a
    Err x -> Debug.crash "unpackOk: Don't call this function on an Err!"

isOk : Result x a -> Bool
isOk res =
  case res of
    Ok  _ -> True
    Err _ -> False

I'm not sure if you can get rid of the default response. And I am a bit worried about the ordering of events.. The responses are asynchronous, so you may get Errs from the input signal on the output signal immediately while an Ok request is still pending. Not sure how to fix that. Not sure if that's a problem for you either.

Upvotes: 2

Related Questions