Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way for flags decoding to fail #17

Open
gampleman opened this issue Jun 13, 2024 · 4 comments
Open

Add a way for flags decoding to fail #17

gampleman opened this issue Jun 13, 2024 · 4 comments

Comments

@gampleman
Copy link

gampleman commented Jun 13, 2024

Most non-trivial apps need to decode their flags from JSON, but this of course has the property that app initialization can fail if the flags fail to decode properly.

One can of course mitigate this by making their shared type into something like:

type Shared
   = Failed DecodeError
   | Succeeded SharedRecord

but this gets annoying, since we need to deal with pattern matching on this shared type everywhere in the application and basically we don't really need the rest of the application if it fails to initialize, since the only thing we can do is show some sort of error screen.

I would then suggest to change Spa.application (or make a new version of it if backwards compatibility is a concern) to something like:

application: 
( ( Msg route currentMsg previousMsg -> Msg sharedMsg (Msg route currentMsg previousMsg) )
      -> pageView
      -> view
    )
    -> { toRoute : Url -> route
       , decodeFlags : Decoder flags
       , init : flags -> Key -> ( shared, Cmd sharedMsg )
       , subscriptions : shared -> Sub sharedMsg
       , update : sharedMsg -> shared -> ( shared, Cmd sharedMsg )
       , protectPage : route -> String
       , errorPage : Exception -> Document Never -- or whatever
       , toDocument :
             shared
             -> view
             -> Document (Msg sharedMsg (Msg route currentMsg previousMsg))
       }
    -> Builder
           route
           identity
           shared
           sharedMsg
           pageView
           current
           previous
           currentMsg
           previousMsg
    -> Application
           -- flags not needed here I think, since this would now be Json.Encode.Value
           shared
           sharedMsg
           route
           current
           previous
           currentMsg
           previousMsg

This would then present the errorPage on flag decoding failure. I've found (we had a private fork some time ago) that there is quite a useful feature where Effect.catastrophicFailure can be then added that goes straight to the errorPage.

Another idea to consider would be to somehow recycle the defaultView for this purpose, although I'm not confident the type system would quite allow it.

@gampleman
Copy link
Author

Another thing to consider would be potentially asynchronously initializing. Some applications must perform effects before they can be properly started (even the good old Time.now, it's annoying having to actually store that as a Maybe or need to also provide a flag for that).

@cdevienne
Copy link
Member

I guess something like a "applicationWithLoader" would do the trick.
The loader part would be a mini-app with its own state and view, that has the goal of building the Shared state.
I will think about it.

@cdevienne
Copy link
Member

Hey @gampleman ,
Could you give PR #18 a try and give me some feedback?
Thanks

@gampleman
Copy link
Author

gampleman commented Jul 4, 2024

Looks pretty good, I'll try to use it in our app tomorrow/next week and see how it works in practice.

On a slightly separate note, I wonder if something like this API sketch would be a useful abstraction for this (if you added flags decoding to it of course).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants