Transcript from the "Handling Edge Cases" Lesson
>> Richard Feldman: Second example, we're gonna turn to the elm-spa-example, that is to say the real-world conduit example that we're gonna be using throughout the workshop. This is the Credentials module. So Credentials holds on to your credentials after you login. So it has an authentication token, as well as your username.
[00:00:15] The authentication token needs to be sent with every HTTP request that goes to the API server, or else it will reject it as invalid, that is, if you need to be logged in to do that thing. So Credentials exposes a limited number of ways to obtain one of these Cred values, Cred being short for credentials.
[00:00:31] So if you've got some Cred, that means you're logged in. So if the only way that we expose to obtain one of these Cred values is from the results of an Http.Request to the server passing some login info, whatever that might be, now we know, okay, if I have a Cred value, that means there must be a user logged in.
[00:00:50] So if I have any function that accepts a Cred value, that means this function only works when you're logged in. Cuz in order to be logged in, you must have run this function first. Now in practice, we can't quite lock it down as much as this. We'll get into why that is a little bit later.
[00:01:05] The point being if we can enforce the idea that the only way to obtain Cred is by logging in, then from then on, we can say okay, if I have some Cred, that means that I am logged in. And if this function requires that I pass it some Cred, that means this function only works in the context of a logged in user.
[00:01:25] So we'll come back to that later, but there's some valuable stuff to be had there. Okay, so for the next example, I wanna look at following. So you have this notion of authors who write these articles, and you can follow them. If you're following an author, that means that they show up in your feed, their articles show up in your personalized feed.
[00:01:43] So when I first wrote this function a couple of years ago, I wrote it like this. I said follow takes a Bool for whether not I'm gonna follow this person. And it takes an Author, and then it returns Html Msg. Which is to say, this renders a follow button.
[00:01:57] So when we render it, if I pass true, then it's gonna say, this is a box to follow the user. If I pass false, it's gonna render a box that says, this will unfollow the user. Now, when I later came back and revisited this, I actually changed this a little bit.
[00:02:12] I added Cred as an argument there. Because you should only be able to follow or unfollow people when you're logged in. It doesn't actually make sense to have a follow button as a logged out user. So I wanted to rule that out. I wanted to make sure that I was never accidentally rendering a do-nothing follow button, when I'm logged out.
[00:02:26] And just by adding that argument, even if I don't end up using the argument, that ends up being something that we can do, again, because Cred is an opaque type. Because the only way to get Cred is by being logged in. Another thing that I noticed about this as I revisited it later is this Boolean is a little bit confusing.
[00:02:44] What does it mean? Does it mean that if I pass true, am I going to get a button that follows the user? Or does true mean I'm already following the user, and actually this is gonna render an unfollow button? Which is it? I mean, I could interpret it either way.
[00:02:57] So later on, I kinda realized, you know what, that's confusing. I'm just gonna make two functions, follow and unfollow. So each of them has one fewer parameter, and it's extremely clear now. This is either a follow button or it's an unfollow button. That's what it does. This is something that I've sorta come to appreciate over time.
[00:03:14] And it's also an idea that we're gonna revisit again throughout the course of the workshop, is the idea of when do you want configuration, versus when do you just want to split out another function? And I think that's something that is not necessarily obvious at first blush. But over time, I've sorta developed more of a sense of this, and I wanna talk about those trade-offs.
[00:03:32] As previously noted, the edge cases can be easy to miss. And one way we can make them less easy to miss is, make it so that the code only compiles if the edge cases are handled. So let's talk about a specific example, and we're gonna go to the code!
[00:03:48] This slide appears many times throughout the workshop. And it's the sign that we're about to switch over to the editor and actually dive into some code.