I am trying to capture and log errors at every possible location in my Elmish (Fable) application.
If I have added a logging handler using Program.withErrorHandler, do I also need to add logging code to the Error case of each cmd.ofAsync invocation as well?
StackOverflow says to show some code, so here is my state update function:
| ZipCodeChanged (ZipCode s) ->
let newZip, cmd =
if s |> ZipCode.looksLikeAZipCode then
let cmd = Cmd.ofAsync api.LookupZipCode (ZipCode s) LookupZipCodeResponse LookupZipCodeError
InvalidInput (ZipCode s, [ValidationError "Validating ZIP Code ..."]), cmd
else
InvalidInput (ZipCode s, [ValidationError "Please inputs a 5 digit numeric ZIP Code."]), Cmd.none
{ model with ZipCode = newZip }, cmd
| LookupZipCodeResponse (posOpt) ->
(... eliminated for brevity ...)
| LookupZipCodeError e ->
{ model with ZipCode = InvalidInput (ZipCode "", [ValidationError (sprintf "Error validating ZIPCode: %s" e.Message)]) }, Cmd.none
This code treats the ZipCode as "InvalidInput" with a user-friendly validation message the entire time until a successful LookupZipCodeResponse is received.
But if that call to the backend API fails, do I need to add my own logging code in LookupZipCodeError, if I have already provided logging the function that I provided to Program.withErrorHandler?
You do have to add logging code to LookupZipCodeError
: Program.withErrorHandler
handles uncaught errors in update
, and Cmd.ofAsync
actually catches error cases of the call and wraps them in a LookupZipCodeError
msg.