Elm Language

Debugging

Syntax#

  • Debug.log “tag” anyValue

Remarks#

Debug.log takes two parameters, a String to tag the debug output in the console (so you know where it’s coming from / what the message corresponds to), and a value of any type. Debug.log executes the side-effect of logging the tag and the value to the JavaScript console, and then returns the value. The implementation in JS might look something like:

function log (tag, value){
    console.log(tag, value);
    return value
}

JavaScript has implicit conversions, so value doesn’t have to be explicitly converted to a String for the above code to work. However, Elm types must be explicitly converted to a String, and the Native code for Debug.log shows this in action.

Logging a value without interrupting computations

Debug.log’s second argument is always returned, so you could write code like the following and it would just work:

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case Debug.log "The Message" msg of
        Something ->
            ...

Replacing case msg of with case Debug.log "The Message" msg of will cause the current message to be logged the console every time the update function is called, but changes nothing else.

Piping a Debug.log

At run time the following would display a list of url in your console and continue computation

payload =
    [{url:..., title:...}, {url=..., title=...}]

main = 
    payload
        |> List.map .url -- only takes the url
        |> Debug.log " My list of URLs" -- pass the url list to Debug.log and return it
        |> doSomething -- do something with the url list

Time-traveling debugger

At the time of writing (July 2016) elm-reactor has been temporarily stripped of its time traveling functionality. It’s possible to get it, though, using the jinjor/elm-time-travel package.

It’s usage mirrors Html.App or Navigation modules’ program* functions, for example instead of:

import Html.App

main =
    Html.App.program
        { init = init
        , update = update
        , view = view
        , subscriptions = subscriptions
        }

you’d write:

import TimeTravel.Html.App

main =
    TimeTravel.Html.App.program
        { init = init
        , update = update
        , view = view
        , subscriptions = subscriptions
        }

(Of course, after installing the package with elm-package.)

The interface of your app changes as a result, see one of the demos.

Since version 0.18.0 you can simply can compile your program with the --debug flag and get time travel debugging with no additional effort.

Debug.Crash

case thing of
    Cat ->
        meow
    Bike ->
        ride
    Sandwich ->
        eat
    _ ->
        Debug.crash "Not yet implemented"

You can use Debug.crash when you want the program to fail, typically used when you’re in the middle of implementing a case expression. It is not recommended to use Debug.crash instead of using a Maybe or Result type for unexpected inputs, but typically only during the course of development (i.e. you typically wouldn’t publish Elm code which uses Debug.crash).

Debug.crash takes one String value, the error message to show when crashing. Note that Elm will also output the name of the module and the line of the crash, and if the crash is in a case expression, it will indicate the value of the case.


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow