Hi, sorry if this is a frequently asked question, but I’ve been digging around for hours and have found only bits of information, with no clear answer - also very much my first rodeo with Elm, so bear with me
In a nutshell, I have this case:
type PlayerUpdate = Playing decodePlayerUpdate : D.Decoder PlayerUpdate decodePlayerUpdate = D.field "update" D.string |> D.andThen decodePlayerUpdateType decodePlayerUpdateType : String -> D.Decoder PlayerUpdate decodePlayerUpdateType kind = case kind of "playing" -> D.succeed Playing _ -> D.fail "invalid update type" port playerUpdateReceiver : (E.Value -> msg) -> Sub msg -- + Some code for hooking this up to a subscription, which uses the above decodePlayerUpdate
My API surface currently only permits “playing”, of course - if anything else is sent, this is a failure. I’d like my application to crash and burn if this happens, because it means something has gone horribly wrong on the JS side.
Now, of course I need to handle all result cases, and this is excellent, but the only way to handle this failure case is to bubble this all the way up to the model. For the moment, I just return my model unchanged, ignoring the error. This is obviously bad.
I think I have two options:
- Reflect the failure in my view somehow, adding a user-visible failure message, and add a state in which any update doesn’t change the model anymore.
- Cute, but this means I can’t check for it in programmatic testing too easily, and I don’t actually want to expose this to a user - ideally this traces to some kind of analytics tool instead.
Debug.logdoesn’t help, sadly, at least according to the documentation it’s optimized away.
- Send a debug message to JS so that it can print to the console, and mess with the elm runtime enough that it stops moving.
- JS is misbehaving, so I can’t really trust this message to be delivered. This might even cause a recursive failure, where each message triggers another.
- I’d rather not mess with elm internals from within JS, this is a horrible idea and I feel bad for even having it.
Obviously, neither of these options is particularly appealing. Worse yet, they come with a fair bit of additional type management, and make the json decoding and model management code more complex than it needs to be, for data that I ultimately ignore in a case that should never happen (and I can be reasonably sure will never happen by synchronizing my typescript and elm models of this internal API).
In e.g. Rust, I would mark this with a
.expect() a bit further down the line so that I can get a nice way to trace the error if this does ever happen in production. As best as I can tell, a
Debug.crash used to exist before elm 0.19 and was used for these kinds of cases, but has since been removed.
Am I simply falling afoul of an ideological pursuit of always modelling the whole application state? Is there some way to poke a hole in here and actually get a stack trace when I want one? Or am I modelling my ports entirely wrong and there is a nicer way to get variants out of my port?