And How it Contrasts with Javascript ------------------------------------ In [Javascript](https://hackernoon.com/tagged/javascript) there are a handful of ways to deal with situations that don’t follow the happy path. * You could **be disciplined** by protectively checking values and **return safe responses**. * You could **be exhaustively disciplined by doing TDD** as much as possible. * You could use **try-catch and throw** to mimic languages that have checked exceptions. * You could **do nothing** and let runtime errors have a detrimental impact on user experience. When writing Elm apps you’ll inevitably run across a situation when you need to handle a non-happy path situation. Your first intuition may be to look for the strategy that you used on that one Javascript project, but that other way may not be available to you with Elm. In this post I’ll outline the types of “error” situations you can find yourself in when writing Elm applications and I’ll describe how Elm makes handling these situations pleasant and safe. ### Unexpected Types The first type of error that you’ll find in Javascript is a **type error**. It’s the notorious _undefined is not a function_ or _cannot read property “something” of undefined_. In Elm applications, you will **never see this error**. Elm is a statically typed language and it has the following protections in place. #### The Compiler The compiler will guarantee that if you declare a constant as a String, for example, that constant could only ever be treated as a String. It can’t be an Int. It can’t be null. It can’t be undefined. If you attempt to make it anything other than a String the application _will not compile_. #### Immutable Constants Elm doesn’t have variables that can be reassigned to different values or types. Elm has **immutable constants**, or perhaps better thought of as _zero argument pure functions_. As such, your declarations can’t change types out from under you. #### Maybes Many languages treat null and undefined as subtypes. This is the infamous [billion dollar mistake](https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions). In Elm the equivalent of null is called **Nothing**, and it is one of the tag names in a tagged union called a **Maybe**. > Elm treats _nullability as a separate type_ Said differently, Elm treats _nullability as a separate type_. As a result, the concept of _null_ must be handled explicitly as part of the type system, thus preventing many common runtime errors. ### Unexpected Data Applications receiving input from the outside world will inevitably receive data in a _shape or type that it wasn’t expecting_. In Elm there are a couple of entry points where data from the outside world can be received. #### Messages from Html.Event handlers Messages dispatched from Html.Event have [specific types](http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Events#onInput) and are therefore guaranteed to supply the Elm app with a Message and a payload of the correct type. This is yet another example of the type system guaranteeing that you’re going to handle the right type of value without you doing any additional work. #### Messages from Tasks Tasks are how you perform most side-effects, such as performing Http requests. One of the arguments that must be provided for performing an [Http request](http://package.elm-lang.org/packages/elm-lang/http/1.0.0/Http#get) is a Decoder. A [Decoder](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Json-Decode#Decoder) is a composable type that Elm uses to transform JSON into a type that you can work with. Elm accomplishes this by handing you a [Result](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Result#Result) which is a specialized [either type](https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Either.html) that will either hold an error (a failure to transform the JSON) or a success value (the transformed value). > Elm hands you a specialized either type, called a Result If there is an error then the compiler will force you to handle that error. This is your opportunity to update the application state with an indication that unexpected data was received. ### Async Failures When making HTTP requests those requests can ultimately fail for a variety of reasons. With Javascript you’ll pass a _success callback_ to handle successful responses and there’s an _optional failure callback_ to handle failures. Elm is different. Rather than exposing an optional failure callback you’ll instead be asked to provide [a callback](http://package.elm-lang.org/packages/elm-lang/http/1.0.0/Http#send) that accepts a Result (the same specialized either type discussed above) as input and that callback returns a Message that will likely be different depending on the Result. What this means is async errors have to be explicitly handled, as opposed to being _accidentally forgotten_. ### Preventing errors with carefully designed data structures By far, my favorite type of error to handle is _absolutely no error at all_. If a bad situation can occur, and you can reasonably prevent it, why not prevent it? The way to accomplish this can best be elaborated by Richard Feldman’s [_Make Impossible States Impossible_](https://www.youtube.com/watch?v=IcgmSRJHu_8) talk but my current two favorite examples that apply this idea are Kris Jenkins’ [RemoteData](http://package.elm-lang.org/packages/krisajenkins/remotedata/4.3.0/RemoteData#RemoteData) package and Max Goldstein’s [elm-nonempty-list](http://package.elm-lang.org/packages/mgold/elm-nonempty-list/latest) package. Here’s a demonstration of using RemoteData. RemoteData Example In using this package we’re preventing a certain “error scenario” where the view could be out of sync with what is actually happening during a request. Because RemoteData is a _type_ in the Model, the compiler will force you to handle the four different Tags that the RemoteData can be, thus forcing you to explicitly handle in the view layer the different parts of the asynchronous request’s lifecycle. ### Caveats I lied in the **Unexpected Data** section above. There are actually two more ways that an Elm application can receive data from the outside world. 1. On app initialization with [Html.programWithFlags](http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html#programWithFlags) 2. When receiving Messages from ports In my opinion, the current version of Elm (0.18) doesn’t handle these situations so well when it comes to _error handling_. When using programWithFlags it’s possible to have a [runtime exception](https://ellie-app.com/kMCYQWs2SY/0) when the application is initialized with a value that it’s not expecting. When using a port subscription it’s possible to have a [runtime exception](https://ellie-app.com/kMrLDkgryQ/0) yet again when an unexpected value is sent to the Elm application. _(open the console to see the errors)_ I asked about both of these specifically and [the response](https://www.reddit.com/r/elm/comments/5tgiyx/why_dont_ports_and_htmlprogramwithflags_use/ddmkaz6/) I got indicated that ports and programWithFlags predated Decoders, and that we shouldn’t expect that [design](https://hackernoon.com/tagged/design) decision to change in the near future, which is fine. There was also a helpful suggestion to use **Json.Decode.Value**. In other words, declaring the data as a JSON value will force you to use a Decoder to turn the JSON value into a type that your Elm application can use. So the best answer I have to these two situations is to **be disciplined** and use **Json.Decode.Value** when using programWithFlags and port subscriptions. It’s a pattern that’s consistent with explicitly handling errors and preventing runtime exceptions. ### Concluding Remarks I find handling error situations in Elm to be a rather pleasant experience. Elm will force you to handle errors essentially by leveraging the type system which is great both in its simplicity and the resulting developer experience. I suppose one of the bigger takeaways from this post is if you happen to be working on a Javascript application you can employ these same strategies by adding a _static type_ implementation that also has the equivalent of _tagged unions_. I realize it’s easy to say and harder to do. But for me at least it’s good to know that I can leverage some of the benefits that I get with Elm by introducing static types to the Javascript applications that I work on. > [Hacker Noon](http://bit.ly/Hackernoon) is how hackers start their afternoons. We’re a part of the [@AMI](http://bit.ly/atAMIatAMI)family. We are now [accepting submissions](http://bit.ly/hackernoonsubmission) and happy to [discuss advertising &sponsorship](mailto:partners@amipublications.com) opportunities. > To learn more, [read our about page](https://goo.gl/4ofytp), [like/message us on Facebook](http://bit.ly/HackernoonFB), or simply, [tweet/DM @HackerNoon.](https://goo.gl/k7XYbx) > If you enjoyed this story, we recommend reading our [latest tech stories](http://bit.ly/hackernoonlatestt) and [trending tech stories](https://hackernoon.com/trending). Until next time, don’t take the realities of the world for granted!