Debug.todo “uncatchable” exception?

In the docs for Debug.todo (and Debug.crash before it), it says:

The Elm compiler recognizes each Debug.todo so if you run into it, you get an uncatchable runtime exception that includes the module name and line number.

I’d like to understand what the technical meaning of “uncatchable” is in this sentence.

For context, we’ve been progressively upgrading our Elm 0.18 codebase to Elm 0.19. We have yet to enable the --optimize flag for our Elm 0.19 builds, because in a number of places we are using code like this:

case something of
    Value1 ->
        -- …

    Value2 ->
        -- …

    ImpossibleValue ->
        Debug.todo "This is meant to be impossible."

Of course we do our best to “make impossible states impossible” using the type system, but every once in awhile, despite our best efforts to model our data and state accurately, we do end up having to provide an implementation for a message that we expect we’ll never get. Of course if we turn out to be wrong about this, we want to find out, so we had been using Debug.crash in Elm 0.18 (which is now Debug.todo in Elm 0.19) to throw an error that we hoped would get picked up by our JavaScript error monitoring.

That said, so far we have yet to see any such errors turn up in our monitoring, and I’m wondering if this word “uncatchable” might have something to do with it. Is there something special about the way Debug.todo works that might prevent a JavaScript error reporting library from responding to and notifying us of the error?

For anyone who might be wondering the “right” way to do this, we do have some of our Elm apps well integrated with our error tracking via a port. We aim to roll this approach out across all our codebases in time.

Looking at the source both both Debug.crash (0.18) and Debug.todo (0.19), they basically do:

throw new Error(message);

under the hood. Not sure if that’s catcheable on the JS side or not.

Seems catchable to me:

try {
	throw new Error("this is a test");
} catch (e) {
	console.log("I caught it: " + e.toString());
// [Log] I caught it: Error: this is a test

I think it means that it’s uncatchable from within the Elm. Definitely you can catch it on JS side and do wary ever you want with it, e.g. log the error, or send it back to Elm via ports.


I don’t think you can use try {...} catch (error) {} to catch errors thrown by Elm, since they happen asynchronously. They should however appear in window.onerror.


Having done some testing, we’ve found that our JavaScript error notification library (Bugsnag) does indeed catch and report Debug.todo errors from Elm. While replacing these errors with commands sent to a port would enable us to use the --optimize flag, we would lose the module name and line number in the error message that we get now. We may still choose to do this for the benefits of --optimize.


I usually have a String field with the location of the port error logging where I put the name of the module and the Tag where this error occurred. That is plenty information in order to trace it back since this type of code should be very infrequent.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.