 I'm actually going to try and stay put this time, because the last time when I spoke at this conference, they gave me a hand microphone, and I kept walking over there, so they had to adjust the spotlight, and then I would walk back here, and they had to adjust it again. I did that a couple of times, and then in the middle of the talk, they were like, she's not going to stop this, and then they just switched on the stage lights, and no idea what was happening. I was like, so I'm just going to try and stay here. All right, so as you might have guessed, I'm Laura. I'm software engineer. I work for a company in Tokyo right now. We mostly put iBeacons into vending machines and then do a lot of cool stuff with them and some more things. But you can ask me about that later if you want to. And I'm going to talk about writing better errors today. What I'm not going to talk about is how to craft the perfect error message, because I feel like there's already a lot of literature and talks and stuff about that out there. But what I've always been missing is kind of that step before, to figure out what you actually want to say and to whom. So I want to take a step back and talk about the high-level perspective, more about the approach, how do we communicate errors. I recently got a room bar from a friend who is moving away from Tokyo. And if you don't know what it is, it's kind of like a tiny little vacuum cleaning robot which goes around on your floors and cleans them. So I got it and I brought it home and then I wanted it to clean my floors. So I put it on my floor. And I pushed a big clean button and I expected it to clean, but it refused. Instead, it started blinking at me. And I was like, I'm not quite sure what it's trying to tell me. And because I'm a highly sophisticated engineer, I decided to approach this issue with a time-tested and proven best practice method. I pushed a random button to see what it does. Maybe we can use a lapel mic to put it to you. No, it's okay. This is kind of far. You put the stand in there. You want me to be closer to the microphone? Yeah, that'll do it. Okay, I can do that. Right. So I pushed this button and it started speaking to me in Japanese. And I was like, I can speak some Japanese. It's not that great. And I was like, I don't know. And I pushed a button a couple more times. And I finally figured out it was kind of trying to say something about error 2. So I deployed another time-tested method, which is Googling the error message. And this is what I got. Error 2 opened Roomba's extractor frame and clean extractors. And eventually I figured out what it actually wanted me to do is to clean the brushes. And so this is like most people nowadays don't really interact with robots every day yet. But what a lot of people do interact with a lot is software on a daily basis. And you kind of get the same stuff there, right? It's like, you see this or like... Okay. And it's not really that helpful, right? And we're like, oh, that's all like desktop software, like, you know, those Photoshop people or let's not even talk about Windows, you know. But we kind of do the same thing to the people that use our stuff. It's like, that's not helpful. Like even more racy stuff, you know. This is not the research you're looking for. I didn't even know I was looking for a resource, but thanks. What do you do with this, right? And so I was starting to think like, what's the problem? Like aside from the fact that these error messages are clearly not helpful at all. Like, why aren't they? And I think the problem with these messages is that they tell you what's the problem. And I was like, isn't that what you want to know? Like there is an error and you kind of want to know what's the problem, right? I was like, is that really what you want to know? And I started thinking some more about this because I was like, huh, I am frequently on the receiving side of these error messages. But since I'm a developer, I'm probably also somebody who causes other people to face these error messages. And I was like, maybe there should be something done about it. So I was kind of trying to take a step back and was like, if there's an error, like what is this error? And what am I trying to say about this error? And who the hell am I even talking to? And so I figured, and I was like, okay, who am I talking to? Whenever I have an error, there are probably some different audiences. What could these audiences be that would be interested in this error that just happened? So first of all, we have the developer. Like we have a product, we have an app or something. There's a person on the back end, assuming we have a server client architecture. There's a person on the back end that writes this stuff. And their job is to figure out how to fix errors that shouldn't happen. Who else do we have? We have people that use our stuff. If we have an API, our product is an API or has an API, we have an API user and what they need to do is to figure out how to correctly call the endpoints that we provide to them and get the response that they expect. And last but not least, we have this guy. If our thing is our product is an app, a web app or a mobile app or something. We have the person that actually needs to figure out how to use this app and how to do the things that we promised them they can do with our product. So now we have our audiences, the other users and the developers. Different types of users, the developer writes the thing. Now we have errors. And for this one, I'm going to really generalize a lot. But I feel like it's helpful categories. We have user errors. I call them user errors. These are errors that are actually caused by the user, by inputting things that are incorrect. And these errors are expected. They have rules. So we know, like, there's images and you should only upload images up to this size. Or you have to input something can be longer than this stuff like that. You're not supposed to use a credit card that's expired. So it's not necessarily to use this fault, but they cause it. And if they know the rules and they follow the rules, maybe that's a little German in me. I'm like, just follow the rules and everything's going to be okay. So if you follow the rules, then the error goes away. And then we have this other type of error, which I'm going to call the server error for now. It's stuff that happens, like, in your code, in the back end. And it's unexpected. It has no rules. Like, there's nobody that, like, no error message that you can possibly write for a bug that tells you right away, like, oh, here's what it is, and this is how you fix it. It would be great, but unfortunately, it doesn't usually happen. So you actually need to go and investigate if something like this happens before you can fix it. So our two types of errors are the user errors and server errors. And now we can chart this up. We have users. We have developers. We have user errors and server errors. And now we can think, like, who actually cares about all of this stuff? Like, who sees what and who's like, oh, this is my thing. Like, I got to deal with this. If I have a user that faces a user error, that's something they can fix. They just need to input the right thing. They need to know what they should input and then do it. A developer that writes this code, like, at the point when the user actually inputs something, you can't really stop them. Like, there's nothing you can do about it. You can try to make it clear and everything, but if they do something wrong, you can't stop them. So you kind of can't really fix this. On the other hand, if you have a server error, a user can't really do anything about it. They can't go into your code and kind of try to fix the bug and you don't really want to anyways. You can and you must, however, fix your server errors. Like, if there's a bug, you have to go and find it and fix it. So what you really care about as a user is the user errors. These are the ones that you have to handle or deal with and as a developer, you mostly want to know about the server errors. And as we already figured out, server errors and bugs mostly, you have to know what's the problem. Because you have to figure out on your own, like, what's wrong. You have to have all the information that you can get to debug. However, as a user of an app, I have exactly zero interest in debugging this app that I'm using right now, or this API that I'm using right now. I just want to use it. Here we go. So I don't really want to know what's the problem. That's just a step on the way. What I really want to know is how do I make this problem go away? And now if we look at this kind of error message, guess who wrote this? The person who wrote this is a person that is used to dealing with errors on their side, where they don't really have a solution of how to make it go away. They just want to know what's the problem. And that's what they tell the other person as well. For them, however, it's not actually what they want to know. So if we keep that in mind and look at it more on a, I guess, like a system level or a flow level, this is my extremely creative flow diagram. When we have a request coming in from some kind of interface, like no matter if it's like an API or like an app or whatever, an error happens here. What do we do? If this is an error that is actually interesting for me, the developer, I got to log it. Like I got to be informed about this error. I got to know what happened. So this is basically a logging. And you want to put everything there that tells this person what is the problem. On the other hand, I also got to communicate it back to the interface. And here I really don't want to know what's the problem. I want to know how do I make it go away? Can I make it go away? So we're splitting this up. We're deciding what is this? What kind of error is this? And who am I talking to about this error? And now that we know that, we can kind of think about a bit more, how do we communicate this? Because now we know what we want to say and to whom. So what about user errors as a developer? Is that something that interests me at all? Most of the time, I'm kind of like, I don't really care. However, this is something that I've actually experienced on products that I've worked on. If you constantly get input about users not being able to do a thing or they always make errors, they do the wrong thing, you can kind of turn on to selectively log input errors, like this kind of errors on an info level and see how often they happen and at which point they happen. And if you're like, oh, like every second person like trying to do this gets it wrong, then I have to rethink my interface. Then you go and talk to the UX people or whoever made this thing to figure out how can we actually not make this happen so much. Because we have to communicate the rules to the user, but in this case, me as a developer, I actually want to know how to not make it happen. As a user on the other hand, I'm concerned at this point like how do I make it work? So what do I want? As an app user, first of all, I want really clear and readable layout. I don't want to kind of try and have to kind of look around and see what it actually is. I want to see it right away and when it's super clear, I want to localize if possible. If I have no way to tell what kind of language this user speaks, I have to make a reasonable assumption about a default. It can be English depending on the country. If you're in a country where you can't assume, everybody speaks English really well. You have to then do something else. For example, in Japan, it's usually not a reasonable assumption to make English error messages. You probably want Japanese. You really want to provide a clear course of action to solve the problem, no matter what it is. You tell them you uploaded something that is too big, upload something that is maximum one megabyte, or your credit card is expired, use a credit card that is not expired. Use a coupon that hasn't been used yet, whatever it is. Tell them what to do. That kind of ties in with the other one. If you want to minimize these errors from happening in the first place, the best error is the error that never shows up, that never happens. You want a lot of front-end validations for stuff that you can validate in the front-end, and you want good UX for people to understand what they actually are supposed to do. If we have API users, the thing about them is, they usually are developers also. They just can't look into your source code. They have to talk to you through this API interface. They kind of understand. You don't have to guide them along that much, because they're used to debugging also. But you want to make it super easy for them to know what went wrong and how they can make it right. So, use matching HTTP status codes. There's actually... So, there's a service that I have had to use at work, and they have an API, and this API has an endpoint, like an endpoint one, and to tell this endpoint what to do is you put into the body of your request an ID that says, for example, I want to do, like, register something. You put ID 022, and like all the other parameters, and then you send it, and this endpoint will always return 200 okay. No matter what happens. And then in the body of the response, you will have an error code. If there is a result, which is 0 if everything was all right, 1 if there was an error, then you have an error code, which tells you what kind of error it was, and then you have a detail error code, which tells you what kind of detail error it was, and then you have to go and look at a gigantic list of custom error codes to figure out what went wrong. A person on Twitter, like I shared this on Twitter, and a person came up with the app description of this as 200 okay, but... So you can, like, I mean, as it says in the second point, put in specific error messages, put all the custom codes you want, but still use reasonable HTTP status codes. There's a reason why there are standards for this, right? And include everything into the response that makes it clear what to do. Like you say, like, parameter something is missing. If you just say parameter missing, that's not helpful. Parameter blah is missing. Our validation failed because here is, like, how to make a valid request. Also, kind of like the front-end validations on the app user side and the good UX, write really clear documentation because API users do occasionally read the manual, so give them one. It's going to be a lot less trouble for you afterwards, and that's the API user. What about server errors? As a developer, this is something I care about a lot because I need to fix them. So you want to make sure that your code has robust error handling. Like, if there is a bug or an unexpected error, you want to kind of minimize the damage. You don't want everything to crash and burn. You want to log it and report it, like you use, like, air brake or roll bar or whatever, and include as much information as possible. Like, most of these services, like, they give you a gem or something that you can include, and they already pull out a lot of info, like, they give you the backtrace, they give you the actual error, they give you the parameters and everything, but whatever else you have and you think might help you actually reconstruct this error and be able to redo it and find what is the actual issue, put it all in. Like, send it to your logging service. Do make sure that someone actually gets notified because you can have all the logging in the world and all the error reporting in the world if nobody ever looks at it. It's kind of pointless. So what we do, for example, we have our, like, we integrate our roll bar with one of our Slack channels. So whenever there's an error that happens for the first time, that happens repeatedly, we get notifications on Slack if it's a production system. If developers aren't that one, and then you can actually go right away and look at it and evaluate, is it something that you have to fix right now? Something that you can fix later. And if you want to, if there was an actual bug that affected users, you can then announce publicly on a changelog, for example, that it was fixed, so people know, hey, it's not going to happen again. What about users and server errors? It does impact them, right? I mean, they really don't want to know what went wrong because they can't do nothing about it. They do want to know kind of what's going on, especially tell them that it's not their fault. Because if something goes wrong and you don't know the system behind it and you're especially if you're not a developer and you can't guess and you're maybe not even very comfortable with software, you're going to be really scared and you're like, oh, what happened? Like, did I break it? Like, did I break the internet? Did I break something? And so you got to tell them, hey, this is what happened. It's our fault. This is what to do next. And it can be, for example, just try again later. We're like over capacity. We can't serve you right now like just try again later. Or, hey, this is an actual problem with your stuff. Please contact support. I found this little cartoon and I thought that's quite descriptive because like this kind of stuff is scary to users. So if you just say, whoa, error, bam. They're like, what am I going to do now? What am I going to do now? Did I delete my data? Did it charge my credit card? Did it charge it like five times? Can I order again? Like, what do I do? Or you just tell them, hey, something went wrong on our side. You're safe. Just try again later. And they're going to be like, phew, okay. I'm good. Just going to try again later. So instead, for example, of sending something like this, which is still scary. And I'm like, to a developer, it makes sense because this is what happened to a person who doesn't know. It doesn't make any sense at all. It's just scary stuff. You did something wrong. Instead, you do something like that. And you don't even have to go all artsy like if you don't have somebody to draw you like flying whales. You know, it's okay. Like you can just write the message. Like even if it's not nicely styled, just say it. And the 80-20 rule, like, you know, 20% of effort brings you like 80% of the way. So if you just say it, no matter how, it's already going to be much, much better. And this is pretty much what we want, right? For everybody who is interested, everybody in our audience, we want to achieve or we want to enable them to solve the problem that they're facing in the best way possible in the fastest way possible with the minimum of frustration, no matter if it's a developer, if it's a user or anything. And now that we know what we want to say about what kind of error, to who, we can now go out and figure out how to write the perfect error message, how to word things, how to display things. But this step about, like, what am I going to communicate to who? That's like, that's been like the missing link for me of like going from an error happens to what kind of thing do I put into my error message? And this is pretty much what I wanted to share with you. So I hope this is helpful to you when you handle your errors in the future and communicate them to whoever is interested in them. Thank you. Awesome stuff. Thanks, Laura. I think it's a great message to think about the people going to see your errors and give them some direction of the do next. Can we get some questions, please? Yes. Okay. Hi. Thank you for the talk. What do you think is the major problem with, like, because you showed the 500 in Rails error message, and I mean, I've seen it a million times, and I think, oh, what do you think is the reason for that? Because if I can make a comment, I think most people don't know how to kind of, I mean, I wouldn't know how to keep, like, how to track what error happened, because, you know, you have this 500 generic handler in Rails, and then once this exception is happening, you basically lose information of, okay, was it, I don't know, the wrong credit card number, or was it, I don't know, red is a connection broke or something like that. So I think, I'm asking, how would people track what actually happened, especially in Rails? Track is for, like, the developer, like, what error happened, or track for the person who sees it on the front end? So the developer has to basically track what happened, so you can render a meaningful error message. Well, I think for, I guess what I was trying to make clear for 500 errors. I totally think we should talk German, by the way. Like, for server errors, there is, you don't really want this, so if it's a 500, then it's most likely some kind of bug, and you don't really have to communicate to the user, hey, this is exactly the bug that happened because they don't really care. It's not going to work for them until you fix the bug. So for a 500 error, you just want to tell them, hey, something went wrong on our side. So you don't really need to figure out at this point what went wrong and show it to the user, but you as a developer, you need to know, so you want the error handling that actually, like, as the exception gets raised, you catch it or you kind of handle it and log it to your logging system. So you can then get notified and say, like, hey, this is where it happened, this was the error, this is the back trace, and you get it. Cool, thanks. Do you think, actually, it is a good idea to tell the users to try contacting us or something like this, or to try again later these messages? Because I think that if you say try again later, the users will just keep trying, and this bug is, like, you know, over and over, and they are just frustrated because what does it mean later? Does it mean in five minutes or five days? And the other one is when you say contact us, then suddenly you've got 50 emails from users and I saw this error, but me as a developer, I already saw it in my error tracker, so the user actually doesn't have to contact me, I don't need it. So do you think that doesn't it make users only more frustrated because they expect the immediate response from you when they contact me? Yeah, that's a good question, and I think it really depends on the kind of error because, like, even on the server, you get different types of errors. If it's a bug, like, an unexpected error, like, completely unexpected, you've got to fix the bug, like, it goes away. However, if it's, for example, because you temporarily couldn't reach some microservice, or something timed out, and then you're like, okay, I know this is, like, a 503 or a 504 or something, and then you know, like, okay, if they try again, it's probably going to work. Then you can tell them, like, oh, just retry. If it's something where you really want to contact support, that would probably be, like, if you can figure it out by the type of error being raised, then you actually have a problem with your data. You know, like, if something got missing and they're just trying to kind of actually get a resource that's not there anymore, but it should be there, but they won't fix itself. It's not an actual, like, code error, but it's more like a data error, and you probably have to have someone fix it for them, like, specifically for that person or for that user. Yeah. Any other questions? Yeah. Hi. Thank you for your talk. It was exceptional. Thank you. Sorry. I really enjoyed your presentation. I was wondering, for the category of errors when we're just showing 500 pages, where it's something that happened on the back end and we don't need to inform the end user what happened, do you think that that's the type of messaging that belongs on that page is generic enough that it could be a similar thing for all websites? I mean, I guess what I'm trying to get to is is there a... Could we possibly change the 500 page... the default 500 page on Rails such that it's... or the production 500 page such that it's better for end users by default? Is that something you think would be possible, or does it have to be customized per site? Probably, if you want to do it 100%, you can probably customize it per site, but I think it could be a lot better as a default just because if I'm developing, if I'm doing it on my local machine and stuff, then sure, as a developer, I know this internal server error, I know what that means. If it's displayed to a user in production, I think that's actually a very good idea to say something that makes sense out of the box to a person who doesn't know what this is about. Thank you. I have one more comment. I think that if you have a website, you have an application that processes users' money, if users use credit cards or something to pay you, and there is an error on the payment step, you shouldn't contact us, you should tell we will contact you. I think that it's just not developers, but the company's good practice to be proactive because users will panic if they see an error and they provided you their credit card number. I think so. If you actually manage to catch it, some kind of error, that's not a kind of no method error or something, and you know that their payment wasn't processed or it never even reached, for example, the credit card provider tell them, especially about credit card payments, because that's something that people don't think is funny at all. You try to buy something and you're like, oh, did it process? If I order again, will they charge me twice? What happened? Otherwise, if you can't tell, you got to make it so that on the back end you're actually informed. This was a process that involved payment an error happened, please check on this user. Was there a payment? Did it go through or not? How useful do you think HTTP status codes are to users? Which kind of users? Actual app users. You still see quite a lot of 404 pages with the numbers 404 in them. I'm just wondering, is it so common nowadays that people know a 404 means a page cannot be found, or is it still like our developer bias coming in? I guess the thing with the 404 is that's kind of the one status code that's kind of ambiguous, because it could be like this page doesn't exist, like this path per se, or like this actual resource that I was trying to find doesn't exist. So that's one of the bit more difficult ones, but basically it says something wasn't found. I don't think the number means anything to people. It just kind of shows up, but what a lot of websites do is like, oops, we couldn't find what you were looking for, because of something. And then you still kind of, I think it's better to actually say, hey, what should you do, if you can do something. But like the number per se, I don't think it means anything, unless you target, like your target audience is actually a developer, like if you're a GitHub, like people who use your service are developers, so they're going to know what is 404. But if it's something completely unrelated, I think the number probably doesn't mean anything to actual end users. Cool. I think we have time for one last question, if there is any. Do we have anyone else with questions? No? Okay, thank you very much. Thank you.