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

Side effects stop working when runtime exception in subscribe #1046

Open
WhileTruu opened this issue Oct 8, 2019 · 1 comment
Open

Side effects stop working when runtime exception in subscribe #1046

WhileTruu opened this issue Oct 8, 2019 · 1 comment

Comments

@WhileTruu
Copy link

If a runtime exception is caused in the subscribe function in js (such as calling an undefined function), commands are no longer being issued and subscriptions are ignored.

SSCCE

port module Main exposing (main)

import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
import Time


type alias Model =
    { time : Time.Posix }


initialModel : Model
initialModel =
    { time = Time.millisToPosix 0 }


type Msg
    = GotTime Time.Posix
    | ClickedCreateRuntimeExceptionInSubscribe


update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    case msg of
        GotTime time ->
            ( { model | time = time }, Cmd.none )

        ClickedCreateRuntimeExceptionInSubscribe ->
            ( model, createRuntimeExceptionInSubscribe () )


view : Model -> Html Msg
view model =
    div []
        [ div []
            [ text <| String.fromInt <| Time.toHour Time.utc model.time
            , text ":"
            , text <| String.fromInt <| Time.toMinute Time.utc model.time
            , text ":"
            , text <| String.fromInt <| Time.toSecond Time.utc model.time
            ]
        , button [ onClick ClickedCreateRuntimeExceptionInSubscribe ]
            [ text "create runtime exception in subscribe" ]
        ]


port createRuntimeExceptionInSubscribe : () -> Cmd msg


main : Program () Model Msg
main =
    Browser.element
        { init = \_ -> ( initialModel, Cmd.none )
        , view = view
        , update = update
        , subscriptions = \_ -> Time.every 1000 GotTime
        }
var app = Elm.Main.init({ node: document.querySelector('main') })
app.ports.createRuntimeExceptionInSubscribe.subscribe(() => yolo())

Expected

Subscriptions still update the model and cmds can still be issued through update.

Actual

Model can still be updated by user interactions, but subscriptions don't do anything and user interactions have no side effects.

  • Elm: 0.19.0, elm-0.19.1-beta-1
  • Browser: Chrome, Safari
  • Operating System: MacOS, iOS
@rupertlssmith
Copy link

Been discussing this one on slack recently.

I think the call to the susbcription callback function is made here:

https://github.com/elm/core/blob/master/src/Elm/Kernel/Platform.js#L382

Will wrapping this in a try...catch block solve the problem? Have the catch block emmit an error message to the console if any unhandled exception falls through.

Another suggestion is to always use async:

myPort.subscribe(async (value) => {
       stuff();       
});

Can the Elm runtime always invoke the callback with async?

Which solution is better? Happy to make a PR for one.

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