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

Internal error when stateless route's Model and Msg don't match what's expected #507

Open
agj opened this issue Jan 3, 2025 · 1 comment

Comments

@agj
Copy link

agj commented Jan 3, 2025

My stateless route had type alias Model = () and type alias Msg = Never, and I got the below errors pointing to an internal Main.elm file. It was fixed when I changed the types I had to {} and (), respectively.

-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 4th argument to `fooFn` is not what I expect:

544|                             fooFn
545|                                 ModelAbout
546|                                 MsgAbout
547|                                 model
548|>                                (Route.About.route.update
549|>                                     { data = thisPageData
550|>                                     , sharedData = sharedData
551|>                                     , action = Nothing
552|>                                     , routeParams = {}
553|>                                     , path = justPage.path
554|>                                     , url = Just pageUrl
555|>                                     , submit =
556|>                                         \options ->
557|>                                             Pages.Fetcher.submit
558|>                                                 Route.About.w3_decode_ActionData
559|>                                                 options
560|>                                     , navigation = navigation
561|>                                     , concurrentSubmissions =
562|>                                         Dict.map
563|>                                             (\mapUnpack ->
564|>                                                  Pages.ConcurrentSubmission.map
565|>                                                      (\mapUnpack0 ->
566|>                                                           case mapUnpack0 of
567|>                                                               ActionDataAbout justActionData ->
568|>                                                                   Just
569|>                                                                       justActionData
570|>
571|>                                                               _ ->
572|>                                                                   Nothing
573|>                                                      )
574|>                                             )
575|>                                             concurrentSubmissions
576|>                                     , pageFormState = pageFormState
577|>                                     }
578|>                                     msg_
579|>                                     pageModel
580|>                                     model.global

This argument is:

    ( {}, Effect.Effect (), Maybe Shared.Msg )

But `fooFn` needs the 4th argument to be:

    ( Route.About.Model, Effect.Effect Route.About.Msg, Maybe Shared.Msg )

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 3rd argument to this function is not what I expect:

548|                                 (Route.About.route.update
549|                                      { data = thisPageData
550|                                      , sharedData = sharedData
551|                                      , action = Nothing
552|                                      , routeParams = {}
553|                                      , path = justPage.path
554|                                      , url = Just pageUrl
555|                                      , submit =
556|                                          \options ->
557|                                              Pages.Fetcher.submit
558|                                                  Route.About.w3_decode_ActionData
559|                                                  options
560|                                      , navigation = navigation
561|                                      , concurrentSubmissions =
562|                                          Dict.map
563|                                              (\mapUnpack ->
564|                                                   Pages.ConcurrentSubmission.map
565|                                                       (\mapUnpack0 ->
566|                                                            case mapUnpack0 of
567|                                                                ActionDataAbout justActionData ->
568|                                                                    Just
569|                                                                        justActionData
570| 
571|                                                                _ ->
572|                                                                    Nothing
573|                                                       )
574|                                              )
575|                                              concurrentSubmissions
576|                                      , pageFormState = pageFormState
577|                                      }
578|                                      msg_
579|>                                     pageModel
580|                                      model.global

This `pageModel` value is a:

    Route.About.Model

But this function needs the 3rd argument to be:

    {}

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 2nd argument to this function is not what I expect:

548|                                 (Route.About.route.update
549|                                      { data = thisPageData
550|                                      , sharedData = sharedData
551|                                      , action = Nothing
552|                                      , routeParams = {}
553|                                      , path = justPage.path
554|                                      , url = Just pageUrl
555|                                      , submit =
556|                                          \options ->
557|                                              Pages.Fetcher.submit
558|                                                  Route.About.w3_decode_ActionData
559|                                                  options
560|                                      , navigation = navigation
561|                                      , concurrentSubmissions =
562|                                          Dict.map
563|                                              (\mapUnpack ->
564|                                                   Pages.ConcurrentSubmission.map
565|                                                       (\mapUnpack0 ->
566|                                                            case mapUnpack0 of
567|                                                                ActionDataAbout justActionData ->
568|                                                                    Just
569|                                                                        justActionData
570| 
571|                                                                _ ->
572|                                                                    Nothing
573|                                                       )
574|                                              )
575|                                              concurrentSubmissions
576|                                      , pageFormState = pageFormState
577|                                      }
578|>                                     msg_
579|                                      pageModel
580|                                      model.global

This `msg_` value is a:

    Route.About.Msg

But this function needs the 2nd argument to be:

    ()

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 3rd argument to `mapBoth` is not what I expect:

369|                             Tuple.mapBoth
370|                                 ModelAbout
371|                                 (Effect.map MsgAbout)
372|>                                (Route.About.route.init
373|>                                     sharedModel
374|>                                     { data = thisPageData
375|>                                     , sharedData = sharedData
376|>                                     , action =
377|>                                         Maybe.andThen
378|>                                             (\andThenUnpack ->
379|>                                                  case andThenUnpack of
380|>                                                      ActionDataAbout thisActionData ->
381|>                                                          Just thisActionData
382|>
383|>                                                      _ ->
384|>                                                          Nothing
385|>                                             )
386|>                                             actionData
387|>                                     , routeParams = {}
388|>                                     , path =
389|>                                         (Tuple.second justRouteAndPath).path
390|>                                     , url =
391|>                                         Maybe.andThen .pageUrl maybePagePath
392|>                                     , submit =
393|>                                         Pages.Fetcher.submit
394|>                                             Route.About.w3_decode_ActionData
395|>                                     , navigation = Nothing
396|>                                     , concurrentSubmissions = Dict.empty
397|>                                     , pageFormState = Dict.empty
398|>                                     }

This argument is:

    ( {}, Effect.Effect () )

But `mapBoth` needs the 3rd argument to be:

    ( Route.About.Model, Effect.Effect Route.About.Msg )

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 2nd argument to `map` is not what I expect:

723|                                 (View.map
724|                                      (PagesMsg.map MsgAbout)
725|>                                     (Route.About.route.view
726|>                                          model.global
727|>                                          subModel
728|>                                          { data = data
729|>                                          , sharedData = globalData
730|>                                          , routeParams = {}
731|>                                          , action =
732|>                                              Maybe.andThen
733|>                                                  actionDataOrNothing
734|>                                                  actionData
735|>                                          , path = page.path
736|>                                          , url = maybePageUrl
737|>                                          , submit =
738|>                                              Pages.Fetcher.submit
739|>                                                  Route.About.w3_decode_ActionData
740|>                                          , navigation = navigation
741|>                                          , concurrentSubmissions =
742|>                                              Dict.map
743|>                                                  (\mapUnpack ->
744|>                                                       Pages.ConcurrentSubmission.map
745|>                                                           actionDataOrNothing
746|>                                                  )
747|>                                                  concurrentSubmissions
748|>                                          , pageFormState = pageFormState
749|>                                          }

This argument is:

    View.View (PagesMsg.PagesMsg ())

But `map` needs the 2nd argument to be:

    View.View (PagesMsg.PagesMsg Route.About.Msg)

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 2nd argument to this function is not what I expect:

725|                                      (Route.About.route.view
726|                                           model.global
727|>                                          subModel
728|                                           { data = data
729|                                           , sharedData = globalData
730|                                           , routeParams = {}
731|                                           , action =
732|                                               Maybe.andThen
733|                                                   actionDataOrNothing
734|                                                   actionData
735|                                           , path = page.path
736|                                           , url = maybePageUrl
737|                                           , submit =
738|                                               Pages.Fetcher.submit
739|                                                   Route.About.w3_decode_ActionData
740|                                           , navigation = navigation
741|                                           , concurrentSubmissions =
742|                                               Dict.map
743|                                                   (\mapUnpack ->
744|                                                        Pages.ConcurrentSubmission.map
745|                                                            actionDataOrNothing
746|                                                   )
747|                                                   concurrentSubmissions
748|                                           , pageFormState = pageFormState
749|                                           }

This `subModel` value is a:

    Route.About.Model

But this function needs the 2nd argument to be:

    {}

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 2nd argument to `map` is not what I expect:

265|             Maybe.map
266|                 (\mapUnpack -> MsgAbout (mapUnpack thisActionData))
267|                 Route.About.route.onAction
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
The value at .onAction is a:

    Maybe (Route.About.ActionData -> ())

But `map` needs the 2nd argument to be:

    Maybe (Route.About.ActionData -> Route.About.Msg)

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 2nd argument to `map` is not what I expect:

233|                             Sub.map
234|                                 MsgAbout
235|>                                (Route.About.route.subscriptions
236|>                                     {}
237|>                                     path
238|>                                     templateModel
239|>                                     model.global

This argument is:

    Sub ()

But `map` needs the 2nd argument to be:

    Sub Route.About.Msg

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!,-- TYPE MISMATCH --------------- [redacted]/elm-stuff/elm-pages/.elm-pages/Main.elm

The 3rd argument to this function is not what I expect:

235|                                 (Route.About.route.subscriptions
236|                                      {}
237|                                      path
238|>                                     templateModel
239|                                      model.global

This `templateModel` value is a:

    Route.About.Model

But this function needs the 3rd argument to be:

    {}

Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!
@dillonkearns
Copy link
Owner

Thank you for reporting the issue! I don't have the bandwidth to work on this at the moment, but it's great to have this for reference.

I think it would be possible to solve the simplest case of this with the elm-review setup that I currently use for reporting errors like this to give better user-facing error messages (NoContractViolations). However, it would be hard to get it to do things like fully resolving type aliases pointing to other types (should be pretty easy to catch the case where type alias Model = {}, though.

The more robust approach would probably be to compile a separate Elm file that will compile successfully if the Model types are as expected, or fail if there are Model mismatches, and then report a more precise error if that fails to compile. Similar to how NoContractViolations is run only when the generated code fails to compile, this Elm file could only be written and compiled in that case as well.

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