Current section: Loading 4 exercises

Handling Error Responses with Remix


00:00 We've got a couple of places that are missing data. We threw up this TS expect error that Lily the life jacket is super not into, so we're going to remove those here really quick so that we can reveal that. Basically, the problem is, this query to our database could potentially give us a null for the user, because maybe the user doesn't exist.

00:18 What we're going to do is add an if statement to say if there's not a user, then we're going to throw a new error. That makes TypeScript happy. But it doesn't exactly make me happy. If I were to go to whatever right here, we're going to get this error that doesn't look good at all.

00:38 Again, we're going to be actually making it look nice later, but the error message itself is not very helpful. The network request gives us a status of 500. Search engines and browsers and things operate differently based on the status code that you return. It actually is very important to give a proper status code,

00:57 even though we're not going to be able to give them a really helpful resolution to this sort of thing. We'll basically just say, yeah, sorry, this doesn't exist. But for now, let's just give them a nice status code. Let's say new response, and we can at least give it a nicer error,

01:16 something like user not found, and then a status of 404. Just with that change now, we're getting our status of 404. If you look at the headers right here, we're going to get the status code 404 not found,

01:34 and then the browser can behave appropriately for this particular situation. As cool as it is that we can throw these responses, and Remix will handle those and take those response status codes and everything. Eventually, we can even pass data to

01:53 display some more useful error message. As cool as this is, it would actually be even cooler if we had a nicer abstraction for this. If we could just move this out and make a function that says assert thing, and here's the thing, and it's any type.

02:12 Then we move this into here and we say thing. Then maybe we could provide an error message or something like that. But here we can just say assert thing user, and then move on with our day. If you were to make this assert thing into a proper assertion function, then TypeScript would know about what we're doing here as well.

02:32 In fact, that is precisely what we have done. As the extra credit shows here, you can switch this for invariant response from our app utils miscellaneous. Now TypeScript knows, okay, so it is impossible for the code to

02:50 proceed here if the user is not defined. Let's also add an error message, user not found, and then our status code, status of 404, and now we're getting the same behavior. But in a really nice simple API, we just literally stick that line of code right there,

03:08 and we're handling this error case really nicely. If you want to dive into that invariant response, it's actually not a really complicated function. It has this asserts condition. That's what you're passing in at the first. You have the message, you can offer that as a function, a callback function if you desire,

03:26 and then a response in it that gets added to this response. That's the idea, you're throwing responses. We can do the same thing over here. Now that we know about that abstraction, we'll just use that straight from the start. We'll say, get rid of that, and then invariant response,

03:45 note, and note not found, status 404. There we go, awesome. So then if we come over here, and we say, let's go to this note, we're going to get a nice 404. Still not a great error message page, but it is giving us the right status code, and we'll make the errors better later.

04:03 And we'll do the same thing for our owner. So let's get rid of this TS expect error right there, because we no longer expect there to be an error. We'll say invariant response, owner, and we can say user not found or owner not found. And now if I come here and say whoever,

04:22 now I'm going to get my 404. So that's one of the cool things about Remix is just the ability to throw an error response, or throw a response object, and then Remix will handle that appropriately. And yeah, now we can get rid of this as well.

04:40 We're no longer expecting an error, huzzah. So there you go, that is invariant response. I definitely recommend having a function like this in your application, because it just makes doing this sort of thing a lot easier. But the core idea is that we're throwing responses,

04:58 and we can pass some sort of content body, and the status, and whatever else you want as part of that response, which I think is pretty rad. You could do a redirect as well, which would be pretty cool. And what's nice about doing the throw, rather than a return, because people ask me about that sometimes. If we did a return, you'd have to say,

05:18 okay, here's the maybe response. And then you'd say, if there's a maybe response, then return the maybe response, right? So that wouldn't be nearly as cool as literally just this. So that's why I really actually like the throwing response mechanism that Remix gives us.