Handling 404s5:40 with Kenneth Love
Eventually, someone is going to type in a URL that doesn't exist, or a link is going to expire. Flask can handle these on its own, but it's nice to provide a custom error page. Let's see how to do that.
abort()- Function to immediately end a request with a specified status code.
errorhandler()- Decorator that marks a function as handling a certain status code.
return render_template('template.html'), 404- The
404on the end specifies the status code for the response.
In every web app, at some point, someone is going to go to a bad URL. 0:00 We have some places where that may happen more often than not, namely where we 0:05 follow and unfollow users, or viewing user's stream, or viewing a single post. 0:08 Let's set up a view to handle these 404 errors and trigger them when we need to. 0:13 So we wanna be able to handle when a URL is wrong. 0:18 So like for instance, this one. 0:21 Since this is generated by Flask, 0:23 we don't really have to worry about this being wrong. 0:24 But we're putting in this post ID and it ends up with the URL that looks like this. 0:27 And what if somebody was like, oh, they just you know, fat-fingered it and 0:31 they wanted to go to post 15. 0:34 So it comes out like this, with nothing there. 0:36 And that's okay, but it'd be nice if it rendered like a 404, 0:38 or maybe we tried to go to a user, and we typed their name just slightly wrong. 0:44 We'll get this user doesn't exist. 0:50 So it'd be nice to get something that we can kind of control. 0:52 So, let's go over here to our app.py. 0:55 And we need to add an import up at the top. 1:00 So where we're importing all this stuff from Flask, we need to add one new item, 1:03 which is the word abort. 1:07 So what does abort let us do? 1:09 Abort let's us end a request. 1:12 So post, I think is fine. 1:16 Cuz that's where we're posting a new thing. 1:19 Index is fine. 1:20 Stream we probably wanna add some testing, too. 1:21 So, here we have this if username and username ba, blah, and 1:25 we trying get this username. 1:28 So, let's add in, a try here. 1:29 And I'm gonna actually bump this to the next line, 1:35 just cuz that line's getting a little long. 1:38 So, what if that user doesn't exist? 1:41 We'd get a models.DoesNotExist. 1:45 And then we need to do something, so we're going to abort, and 1:49 we're gonna abort with a 404. 1:51 That's the error [SOUND] code. 1:53 So, 404, if you know HTTP status codes, 404 is the file doesn't exists. 1:57 Technically, our user doesn't exist, so that file doesn't exist. 2:04 The rest of that we can leave alone. 2:07 And let's see. 2:10 What other ones would we want to change like this? 2:11 I think probably the follow would be a good one. 2:13 So, here where the user doesn't exist, this would be a place to do the abort 404, 2:17 and we're gonna wanna do that in unfollow as well. 2:22 And, I think the other place we'd probably want this would be in the view post. 2:27 Sorry, I'm kinda scrolling back and forth a lot. 2:32 Here we have those view posts and I think we probably wanna do like, well, 2:35 I almost wonder if instead of doing a try accept there, we'd really wanna 2:40 do something like, if posts.count single to 0, as if nothing comes back. 2:45 Then we did the import 404. 2:52 So, they put in a number where there is nothing that matches that number. 2:54 We won't get a models that does not exist because we're doing a wear, 2:58 we're doing this filter. 3:01 Where it's just like, hey, give me any posts you have that match this id. 3:02 It could give me 20, it could give me 2, it could give me none. 3:06 And peewee doesn't really care. 3:09 So we have do this kind of check for the if posts.count. 3:12 'Kay. So we've rendered these 404's. 3:15 And let's, let's see what happens there. 3:17 So this is easy, it doesn't exist. 3:19 I get a 404 and this is just a manual standard everyday 404. 3:22 And that's fine. 3:26 We could leave it like this. 3:28 But let's provide one that's a little bit nicer. 3:29 Let's go over to back to our app.py, and 3:31 then down at the very bottom just because it seems cleaner. 3:35 We're gonna add a new view down here. 3:39 And we're gonna say not_found and it's gonna take an error. 3:41 And we're gonna return render_template. 3:45 And we'll call it 404.html. 3:49 And then we're gonna do this comma 404. 3:52 So, what is this? 3:55 This is the status code to send back. 3:56 So we're rendering this template, and this is rendered as a 404. 3:59 The one other thing we have to add to this is a new decorator, 4:03 which is app.errorhandler. 4:07 And we specify 404. 4:10 So, any time a 404 is triggered. 4:11 Our app will use this function. 4:14 And then, of course, we need to go look at our 404.html. 4:17 So let's generate that new template. 4:22 So 404.html. 4:27 And let's do extends layout.html, 4:30 and we'll do block content, do an h1 of 404. 4:36 We'll do a p, and we'll say, Wow, sorry, that page doesn't exist. 4:43 And we'll do a new p, and 4:50 we'll do a a href with a url_for index, 4:53 and we'll say Try again. 4:59 All right? And then we'll end our block. 5:02 Okay. 5:06 So. 5:07 Let's go see how this works. 5:08 Let's refresh this page. 5:10 So we'd probably wanna clean this up some. 5:12 But, it definitely gives us the start. 5:14 And let's see. 5:18 If we were to go here, and go to a post that doesn't exist, same thing. 5:19 Awesome. 5:24 It's nice to see that we can get a reliable and stylish 404 page. 5:25 Great. 5:30 Now are app is more useful to visitors and 5:30 let's them know what's going on if something goes wrong. 5:32 We should probably add views for errors in the 500 range as well, but 5:35 I'll leave that up to you. 5:38
You need to sign up for Treehouse in order to download course files.Sign up