 Let's talk about it. So I definitely recognize some faces in the audience, but for those of you that I don't know, my name is Brittany. I am an instructor and tech lead at Turing School. And if I don't have a chance to meet you before the end of the conference, you can find me on GitHub at Brittany Storros or Twitter or pretty much anywhere on the internet. So today I want to talk about the nightmare that is error handling and error messages. And what we can learn from the pretty minor mistakes that we make and the terrible error messages that we receive in return, okay? So this talk is mostly going to be me complaining at you, but I'm going to assume as developers that we're all cool with that, okay? So since I've been teaching, I've had a lot of students that are coming from very different backgrounds with very different skill sets. So as they're going through the program, certain students are really excelling in certain areas of programming and struggling in others and vice versa. But over the past couple of months, I've really noticed a handful of common and pervasive technical hurdles that really hamper the learning process for students. So a lot of times new developers have a hard time wrapping their head around things like abstraction and modularity. Sometimes things seem like a big black box of magic. The sheer size and number of files in a particular project is really overwhelming. The amount of tools and frameworks and libraries that we're working with make decisions really difficult to make. How do I know if I'm picking the right tool set for the application that I'm building? Obviously, we've always had a problem with writing good documentation. So when people try to go read the docs, sometimes they're just not there for you, okay? So there's a lot of different technical hurdles for new developers in programming. But today I want to focus on error handling. Earlier this week, I was speaking on a panel at Denver Startup Week about navigating the path from being a junior developer to a senior developer. And one of the big themes that came out of that conversation was that the journey to becoming a senior developer is filled with just accumulating failures. You're just making mistakes constantly, and then you're committing them to memory, right? So you're going to keep making a ton of mistakes, but you're going to remember what they were and how frustrated you were and how long you tried to debug them for, okay? And then when you see them again in the future, you're going to be able to fix them a lot faster. You're going to recognize them. And when you see other people struggling with them, you're going to be able to help them as well, okay? So what actually happens when we fail, when we make mistakes in our code and we run into bugs? We usually get these really obscure, confusing error messages. Sometimes they're really unhelpful, often indecipherable. In this particular case, failure is not an option. But we are also told all the other options that are actually possible within this program. And then a lot of them are just very visually offensive and intimidating. This one is literally catastrophic, okay? So these are the types of error messages that we're giving to people when they make a mistake or when they do something trivially wrong in their programming or the way they're using programming. And I have to tell us that this is all our fault. We did this as developers, okay? So we really can't blame this on anybody else. This is our doing. And I think it's our responsibility to fix it as well, okay? So take a minute to just accept that fact. Come to terms with the fact that we're pretty terrible, okay? So I have one admission to make. I'm gonna preface the rest of this talk with an apology and a plea, not to hate me, because I'm actually a JavaScript developer, not a Ruby developer, okay? So I don't know about all the rubies and the gems and the rails that all of you are using. I'm not familiar with all of those. But that makes me a perfect person to give this talk on error handling, okay? So since I've been teaching, I've been working with the front-end program at Turing. And I've seen all of the errors that my students are running into when they're building the front-end of these applications. And as a senior engineer, I had really lost my perspective on how difficult it is to parse certain error messages and call stacks that we're giving to people when they make mistakes in their code bases. Certain messages that were really simple for me to understand and figure out how to fix were completely mysterious to my students. And that's not their fault. That's, again, that's our fault that this is the way the system is working right now, okay? So for example, we use React at Turing School. That's what we're teaching people. And there's one error message where you will just get this very short, terse, uncaught error that says it can't find a particular module. But when you're looking in your code base, you're looking in your text editor and you say, I see that module right there. I know I wrote it. I know I imported it. I can find it. Why can't my program find it? It's actually because there was a syntax error somewhere within that module. And it prevented it from loading, okay? But how is a new developer supposed to understand that? How are they supposed to recognize that? This message does not reflect what actually went wrong. About a year or so ago, I ran into this one, which was really scary. I don't know what I did wrong, okay? I believe it was something with a fetch request to an API endpoint for JSON data. And I must have been doing something with the response body and then trying to reuse it somehow. The only way that I can parse this error message, I still have no idea what I did wrong. But it was pretty creepy when I first got it, okay? And then one of the more recent ones that we ran into, one of my students ran into this actually, and this is the one that sparked me to really pay attention to error handling and make me want to do something about it. We were deploying applications to Heroku. It was their first full stack application that they had built and the first one that they were going to deploy and put on the Internet live somewhere. So it was really exciting. And one of my students, we had gone over Heroku and how to do the deployment process. One of my students was having a problem deploying their application. And I was like, well, we taught you how to look at the error logs in Heroku. How do you look at the error logs? And I was being kind of sassy about it and I was like, go figure it out on your own. Figure out what went wrong by reading the error logs. So I sent my student to the error logs and then in his terminal, literally all that the error message said was we need a better error message. So I actually remember feeling personally embarrassed by this. I had nothing to do with the libraries that we were using, the tech stack. I did not write that error message. But I was embarrassed that we have been tolerating this as an industry, as a culture. And the fact that I had sent one of my students to go look at these logs that I would have assumed would have been reliable and then they weren't. They were absolutely completely useless. So that's what really sparked me to want to think about the error handling culture in JavaScript as a whole and why it was so broken. And I was really aggressively excited about the idea of trying to fix all the places that it was broken in JavaScript. So as I was starting this talk, I kind of went into it with a hypothesis that this can't be the same in all these other languages. No one else will tolerate this. It has to be a JavaScript-specific cultural thing. So you're working with another language, another framework, another library, and no one would put up with error messages that are this bad, right? So that's the hypothesis I was working with initially. And I figured I would test it out by trying to build an application with Ruby on Rails. And I had used Rails in the past a couple years back when I was working at the New York Times, maybe in 2013. I had a hard time with it because I was a much younger developer than they had a lot of applications that were in different versions of Rails. So some of them were in Rails, I think two, and some were in Rails three. And I believe that's when there was a big jump between the different versions. Someone can correct me if I'm wrong. But it was very difficult for me to understand it then. And I was like, okay, now I have a little bit more experience under my belt. Let me see if I can parse some of the errors that I run into when I try to build a Rails app. And the very first thing that I ran into was this hellscape. I don't know if anyone has seen this. Error installing MySQL 2, error failed to build gem, native extension, has anyone seen that? Yeah. See? Okay. Now, I spent a couple hours going down this rabbit hole, luckily the Stack Overflow post that I went to to figure out how to solve it had no less than 50 solutions for me to try. So it took me a while. But eventually I made it through that part. And I started building my little tutorial application. And I ran into this one repeatedly. No method error in PostsController. Undefined method posts for nil, nil class. Who has seen this error? What does that mean? Okay. Right? So this reminds me specifically of an infamous error that we had in JavaScript for years. And we still have it, but it's a lot better now. It was undefined is not a function. You would see it in your console all the time. And there is nothing you could Google about that because the part that you needed, the part that would tell you what was wrong, was undefined. That's what it was called all of a sudden in this error message. So how do you Google something like that? How do you search for something like that? Luckily the browser implementers, the Chrome developers recognized this as a huge pain point for new JavaScript developers trying to parse what that meant and they actually fixed that. So now you'll get the name of the function that you were actually trying to call that was undefined, which is great. So this error reminded me a lot of that. And as a junior developer coming into this, one thing that I see a lot with new developers is that figuring out how to Google things is actually really hard. And if I'm a junior developer and I look at this error message, the part that I'm going to really latch onto is this keyword posts right here because that's what I wrote. That is specific to my code. So it must mean that something is wrong with posts. When I Google that, I'm probably going to copy and paste that whole error message in. Nothing is going to show up because not everyone is making an application that has posts associated with it, right? And it doesn't necessarily actually mean that that's where the error is in my program. Posts might be perfectly fine. It might be the thing right before posts that's broken, this current user that I have here. So it's really hard to tell what's going wrong with an error message like this. The last one that I ran into was no implicit conversion of string into integer. If anyone is familiar with JavaScript, our nice dynamically typed language, we can convert data types into whatever we want. They will just change out from under us on the fly and it's great. We don't get any errors about it. We'll maybe get some weird bugs in our code, but that's fine. We don't care. Okay? So I remember specifically when I was running into this problem, it was very difficult for me to understand where I was trying to convert a string into an integer. I wasn't doing that. It didn't seem like that was an explicit thing that I was attempting to do. What actually wound up happening was I was trying to grab an item from an array with bracket notation that was using a string instead of an integer for the index. And it was trying to convert that data type so that it could grab that element. And that was obviously not going to work out for me, okay? So I don't know if I proved my hypothesis wrong or right. I'm going to hold off on deciding that, but I did recognize after going through this tiny application in the error messages that I ran into that error handling is broken everywhere. It's really broken in a lot of places. And it's broken in a predictable way, okay? So error handling is predictably terrible. And I emphasize the word predictably because I feel like I've recognized a handful of common themes and limitations that we have that make error handling bad, that make error handling broken, okay? So one of the reasons why error handling is so bad is that errors are written for developers and not the users who actually run into them. This one for example. So when I talk about users, yes, I'm talking about users of the application in the traditional sense, people that are your average web browsers, they're not looking into DevTools to see what went wrong. They're just going to sit there confused if your form doesn't submit and they don't know what to do, okay? But I'm also talking about users that are developers and they're working with a new library or new framework or new language. So these developers that are using your tool set, using whatever library or framework that you open sourced for other people to use, they're coming into your application using that in theirs and now those are your users and those are the people that you have to be writing error messages for because they need to know exactly what's going wrong. And we lose this perspective. When you are a maintainer of an open source application or you are the writer of a spec for a language, you have such advanced knowledge of that topic that other people don't have. Someone coming in to use your work is coming in as a junior. I don't care how many years of experience they have as developers, the first time you use a library, you are a junior in that library, okay? So as we get more advanced with the technologies that we're building, the code bases are getting a lot more complex but so are the error messages because you're assuming that everyone is on the same page as you and they're not. Your audience is always going to have junior developers coming into there so you need to focus on your error messages at that level rather than saying, this makes sense to me as a maintainer, I would know what went wrong with this, I would be able to help someone if they ran into this but that puts more work on you and it doesn't mean anything to the new people coming in to use your work, okay? Another reason is that programs can only understand so much about intent so I know we are a little bit scared of AI taking over and getting really smart and worried about stuff like that but I think programs are still very unintelligent, okay? Programs only know so much about what a developer is actually trying to do and that's all that programs can speak to when they throw a new error message. So this error that I ran into, sorry, this might be a little bit tiny but this is a syntax error. So syntax error, unexpected token, less than sign in JSON at position zero. Has anyone seen this before? Okay, a bunch of people. So this is a scenario where you're doing, maybe you're doing a fetch request and you're expecting JSON so you're trying to do like JSON parse or you're doing something assuming that your response that came back from that fetch request is JSON and it's not. Usually in most cases it winds up coming back as HTML, that's kind of the way that we tend to make that mistake so that's why this little less than character is the most frequent if you Google this error message because that's what HTML documents start with. They start with that doc tag so that's going to be the first thing that you see here but you'll see this error message everywhere with like unexpected token E or U or any kind of whatever came back that wasn't JSON. That's all that program knows is that you told it to parse JSON and it can't. It doesn't realize that you had a content type mismatch. It just knows that I'm trying to handle this as JSON and I can't do that. Okay, so it really didn't understand our intent there. It didn't know if we meant to return HTML and we just forgot that that's what we were doing and we tried to parse it. It doesn't know if we are accidentally returning HTML instead of JSON. It doesn't understand that intent behind what we were trying to do there. Okay, the last reason and I think the most overwhelming reason why error handling is so bad is that we're lazy. Okay, we already admitted that we're terrible. So hopefully this isn't a huge blow to anybody's ego but we're really bad about as an industry about making sure that we prioritize error handling when we're building our tools. Error handling has significantly become a nice to have rather than something that we prioritize right off the bat and I think that's really unfortunate and really sad because it just shows how little we're willing to do in order to make a welcoming environment for new developers because this is such a big barrier getting these really cryptic error messages. So I did a really quick search on GitHub for the keywords better error, okay, and I wound up with almost a million issues related to better error messages and better error handling. A lot of them were closed, which is nice, maybe a good sign unless they're all just labeled won't fix, okay, but the fact that all these issues were filed I think is already a sign that that was a secondary concern because people wanted to ship their code, get everything open sourced and then they're like, oh, by the way, let's file issues to make better error handling later. Issues are something that you file so that you can take care of it later. That's how I interpret that. I highlighted this, this is probably a little tiny too, but I was going to use these numbers as part of my hypothesis, but then I didn't realize how, I wasn't sure how to interpret them, but when you search for better error, JavaScript has 135,000 issues with some sort of label around better error handling compared to Ruby's 44,000, I believe, it's almost three times the amount, so at first I thought, yeah, JavaScript is terrible, we just don't write any of our error messages and we don't prioritize this, clearly our ecosystem is a lot sloppier than Ruby's, but then I decided to think of it as we care more and we're more thoughtful about it and we're filing issues because we want to make all these things better, so that's how I'm going to interpret it. You can all interpret it however you'd like as Ruby developers, okay? So we mentioned that the problems with error handling are predictable and as developers, we have a tendency to find and build solutions around predictable errors. Predictable errors or problems are the best types of problems to run into as developers because that means they're solvable, that means there's a pattern to them and that means there's ways that we can fix these things, okay? So fixing error handling, I have a couple of ideas. The first one is self-correcting errors and awareness of intent. So self-correcting errors, we're already doing a little bit of this. This is just output of using RuboCop to do autocorrect, so you can use a flag on RuboCop that just says dash dash autocorrect and it will automatically fix all of your linting errors. We have the same thing in JavaScript with ES lint, okay? So that's really useful for these little code sanitation things. Maybe they're doing this static code analysis and they're saying, okay, you probably didn't intend to create this whole block of unreachable code or to put this line terminator here. Let's try to fix these things for you and that's what it'll do. I don't know about all of you, but I'm kind of at my limit for how much I will allow a program to automatically mutate my code for me. So I think this is as far as I feel comfortable going with programs like that, but I think this concept of awareness of intent, making our programs better able to predict what it is that you're trying to do and offer up recommendations based on that would be super helpful. The other, earlier this week I was talking with a developer at Google who works on V8, their JavaScript engine and he was saying one of their goals is when you have a, say you have a variable that's undefined and you have a ton of other, your code is broken, that's totally fine. This thing is undefined, but we notice that you're using a variable that has a very similar name all throughout the rest of your code base. Did you perhaps fat finger this variable in this particular instance and is that why your code is broken? So that's something that they're working towards being able to do. Do this additional static code analysis to say, okay, we see this variable all over your code base and now it just looks slightly different over here and this is the only place it looks different, maybe that's the source of your problem. So a little bit more around the code analysis that we can do I think would allow our programs to have a little bit more awareness about what we're trying to intend to do as developers. Piggybacking off of that is community support and resources. So when I ran into that MySQL issue, there were, like I said, there were like 50 solutions on that, that Stack Overflow question. We have all of these answers to these bugs on places like Stack Overflow. People on Twitter will be answering questions like this. We have all of that community resource and research that we could be using directly in our error messages. So one of my favorite examples of really good error handling, which I'm not even sure if it counts, is in Chrome's developer tools. In the audits panel, I'm not sure if that has made it down to stable yet. I know it's in Canary, but in the audits panel you can run all these checks on your application around best practices and performance, accessibility, and whenever you have an error in one of those areas, whenever you have a failure in one of those areas, not only will it tell you how you failed, but it gives you a link to learn more about that error. So what is this error? Why is it important? And how do I solve it? So it will link you directly to the docs, write in the error message, and say, follow this guide, follow these instructions, and you'll probably be able to fix this. Okay? I think as developers we have a tendency to want to make things very terse and very concise with our programming, but error messages are not the place to do that. I think we could afford to be a bit more verbose with the error messages that we're creating and give these additional resources and recommendations of places that users might be able to find answers or solutions a little bit more easily rather than having them go Google it. So as you get more experienced when you're developing, yeah, Googling issues becomes a much easier task. You kind of figure out what it is that you need to Google, what parts to leave out, and what parts to put in, and maybe what keywords to add, but that is a skill. That is a skill that you developed over time, and it's very easy to forget that. It's very easy to forget that. It is hard to know what to Google when you run into a particular error message. And I think a lot of people lose that perspective. So when we have these vague errors, it's really hard for people to figure out where to go from there, how to understand that, read that, and where to search, okay? The last thing is writing error messages for our users and not just ourselves. So this one is really important because like I was mentioning earlier, I think my clicker died. No matter how many years of experience you have, we're all juniors when we are learning a new language or tool. You have some skills under your belt that will translate concepts and patterns that will be familiar. But we're all juniors when we're going into these new code bases and learning these new languages. So the audience that you're writing for really needs to be focused on that lower bar. Yesterday I was at a TC39 meeting where implementers and developers of JavaScript are actually working on the specification, the ECMAScript spec. And every new proposal that came up, people were constantly discussing, what is this gonna look like and do to newcomers, to new developers, to JavaScript? Is this syntax too confusing? Is it too hard for them to understand? Does it not fit with our traditional understanding of how JavaScript works and behaves? And that was very frequently a reason why proposals would get shut down. Because every person in that room was taking into consideration that there are constantly new developers learning JavaScript for the first time. And we need to make it easy for them to figure out how to do that, okay? So I think that bar of prioritizing your junior audience is super important. I know we had a theme about trust throughout this whole conference. So I wanna tie that in a little bit before I'm done. And just remind everyone that building trust is a lot in part of how you're gonna support your users. So having really successful and informative error messages is so important to have users that will trust you. I want to be able to build an application in any language with any framework and any library and trust that when I mess up, not only are you gonna tell me about it in a way that I understand, but you're also gonna help me figure out how to fix it, okay? So that's one of the biggest priorities I have when I go into new text acts and new languages. I wanna know that you've done your due diligence in trying to make it easy for people to learn and welcome people to using your application and your software, whatever it is that you're building, okay? That's the end of my complaint. So, thank you for watching. I'll see you next time. Bye.