Fast API Tutorial, Part 19: Handling Errors

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello friends and welcome to part 19 of our fast api tutorial uh in this video we are going to talk about handling errors errors errors okay let's just jump right into it so you're going to have certain situations where you're going to want um you're not going to want to just have fast api handle the errors you're going to want to do something you know if you're building you know if you're building your client application as well as the server application you might want to have certain functionality in the client that will handle said errors and will display a custom error message or something like that you've seen in the past we've we've run into errors um trying to figure out what was going on could have been a little convoluted it could have been a little difficult to try and and see what to do with that error so this would that's going to bother me trying to say the word error the entire time in this so this will allow us to kind of override some of that sort of stuff and put our our own custom functionality on it you'll see so let's just go ahead and get started we're going to say items equals foo the foo wrestlers don't know why sebastian came up with that but that's fine app.get items item id our normal you know our normal stuff async def read item item id is going to be a string and if item id not in items we're going to raise an http exception status code equals 404 detail equals item not found otherwise we're going to return item items item id so we are going to need to import it we can see if i hover over this i can import it from starlit http client or fast api i will import it from fast api but let's go up here and do it from fast api we'll import http exception oh and i had a typo status code there we go better let's go ahead and refresh our page we will pull this and we will try 456 and you can see we got our error here that says not found if we go into localhost hots items four five six that's three thousand why did i do three thousand instead of eight thousand i don't know why i did three thousand there we go we got detail item not found if we were to do something like this if we were to comment this out and try and rerun it we would see we would get this sort of internal server error so what this allows us to do is it allows us to handle that that error and return an actual value item not found and i apologize if you couldn't see it it's not worth zooming in for something like that um the reason that we're raising this and we're not returning it is because excuse me because it's an actual exception that we want to handle we want to do something with it we don't want to just you don't want to have to say you know let's say we're doing this code somewhere else we're abstracting it out and we're going to be reusing in multiple places you don't want to have to handle a return and say if if the if the dictionary key is this then do this if it's this then do this by raising it as an exception you can put it in a try and accept block as an example okay what will also happen is if you raise this http exception in a constituent function constituent function so if we were to abstract this out and put it somewhere else raising this exception would would stop execution of the the rest of the path operation function it would just immediately return the error which is what we would want to have happen um you might not see the benefit of this yet but um down the road when discussing dependencies and security you'll you'll see it a little bit you know a little bit more so let's go ahead and type in foo and see if we can get this to run and there we go we get the we get the result that we anticipated okay you saw when we were importing this we could have imported it from starlit or we could have imported it from fast api the reason we're importing it from fast api is that we can actually add in custom headers we can say headers equals x error a very nice play on words not play on words that's stupid it's not a play in words come on jeff um i don't know what it is but it's the foo fighters so that's where it comes from okay now let's go ahead and refresh our page here try it out four five six it doesn't really tell us anything here but you notice down here we get our custom header that we uh that we handled down there okay okay good now let's go ahead and um extend this a little bit so we don't want to have to manually handle these sort of exceptions um everywhere you know if you want you know you the purpose of a lot of what we're doing in fast api is um code deduplication you know you've seen when we had the base model that we extended off of that was to you know to dry up your code so what we're going to do now is we're going to extend the the base exception and we're going to create custom exception handlers so the first thing that we'll do is we will say class unicorn exception that inheritance exception and we will say in the init method self.name equals name and we have to say name as a string okay perfect now what we're going to do is we're going to say at app exception handler and we're going to say unicorn exception so now and you'll see what's going on in just a second okay don't worry too much about it just yet so what we've done is we first created a class that extends from the base exception class so now what we're doing is we're adding an exception handler to our app that will do something with that exception anytime we raise a unicorn exception then we're going to do something with it so let's call it unicorn exception handler request is going to be a request object and our exception is going to be a unicorn exception and we're going to return a json response with status code equals 418 and content equals nope message and we'll do an f string oops exception.name did something excuse me oh i moved my mouse hold on a second there goes a rainbow i don't want to presume what uh what sebastian was was imbibing while he was writing this documentation but it is fantastic whatever he was using app.get unicorns name and we're going to create our route read unicorn's name is going to be a string if name is yolo raise a unicorn exception with name equals name otherwise we're going to return unicorn name is name and we need to import request which we will import from starlet and then we're going to need to import json response from starlet responses can also import them from vast api so let's just do that request and from from fast api debt responses import json response save it should reformat and now everything should be good to go so let's just see what's what's going on right now okay so we're going to hit this this route let's refresh our page try it out blah so we should get a good response back good we got unicorn name is blah now if we put in yolo what's going to happen you can see we're going to get the teapot error the the fun teapot error now what happens here if name is yolo we're going to raise a unicorn exception with name equals name okay so first thing that's happening is we're instantiating an instance of this unicorn exception class where we're going to set self.name equals to the name that we're passing in in this case it happens to be yolo okay that's the first thing that's happening now what we're doing is we're adding an exception handler to our app that is running this get request it's running the uh the po the get request that's up here and what will happen is when we throw a unicorn exception we are going to handle it in our unicorn exception handler so we're going to grab the exception via the exc instance here and we're going to return a json response so this allows us to say the status code and provide a custom message for any time we want to raise this unicorn exception so we we can have we can have this exception raised in countless um in countless path operations we don't have to set this up every single time we do it okay if you want to add headers each time you can do that in your custom exception handler that's some of the benefit of um of doing it like this as opposed to just putting it directly in the uh directly in the app it's or the the path operation itself um so here let me let me do another one so now we're going to add in add app.exception handler and this time we're going to do request validation error async def validation exception handler request exception return plain text response with the string of the exception and status code equals 400. okay and again we're going to have to import these best api exceptions and this is going to come from probably from fast api response so let's see plain text response and then from fast api dot exceptions import request validation error okay now let's add in let's add a route app.get validation items item id and i'm just doing this because i don't want to have to get rid of this i want to be able to leave this up here for when i commit and then we're going to say oh no not there async def read validation items item id is going to be an int if item id equals three raise http exception status code equals 418 which is our teapot error and detail is nope i don't like three otherwise we return item id is item id okay now let's go ahead and refresh our page let's go into here we hit a five and we get our valid response we type three and we get this okay let's go back into here let's do validation items three and we get that okay now let's um just hold on one second sorry i have a little tickle in my throat i don't know what's going on here so now if we type in instead something like foo we're going to get that it's not going to work because we're telling it it's an item or we're telling it's a an int but if we type it in here you can see we get one validation error for request path item item id value is not a valid integer let's get rid of this or let's comment it out for just a second and see what the response otherwise would be it would be this this is what i was talking about before it's a little cryptic you can figure out what's going on you can see path item id value is not a valid integer but what this will oh no that's not what i want to do what this allows us to do is it allows us to to make something that's a little bit more human readable that we can [Music] you know we can actually see and we can do something with okay so that's that's that one um let's add in another uh another exception handler really quickly uh let's add in app exception handler starlet http exception async def http exception handler request exception return plain text response string exception dot detail status code equals exception dot status code and we need to import starlet http exception starlet exceptions nope that's not where it's coming from um oh http exceptions come on jeff import http exception as starlet http exception it's the same thing we just need to rename it um another way okay let's go ahead back down we rerun this we hold on let's refresh our page right here for a second sorry i had to pause for a second and just double check something okay so let's continue on so we can we can override the the base exception handlers in any number of ways that you want to okay and then we can kind of handle it however you want you know something like that okay next we are going to uh we're going to use the request validation error body okay let's uh let's come down here i'm gonna have to comment this stuff out for now just to uh because i'm gonna be overriding the same thing again app.exception handler request validation error async def validation exception handler request as a request exception is a request validation error oh sorry i click the mouse somewhere by mistake i apologize we're going to return a json response with status code is status http 422 and content is json-able encoder with detail being the errors from the exception and body being the body from the exception let's hit save we're going to need to import json-able encoder json-able i don't know from fast api encoders json-able encoder okay so we now have this exception handler that's going to override any general um request exception okay now we're going to say class item is base it inherits from base model title is a string size is an int and we're going to say app.post items and then async def create item item is an item return item okay now let's go into here create item and let's try sending this in with a with a string hello nope this i didn't want to hit enter there we get our unprocessable entity like we normally do but what we also get is the actual exception body okay so this is just another example of of how you can extend um you know base functionality to kind of provide a little bit more information you you can call this whatever you want to you can call it blah blah and then you can have something in your front end that you we'll say hello again you can have something in your front end that will check to see if blah blah exists in your um in your exception body or in your exception response whatever it is okay so those are those are some of the ways that you can override the exception handlers we can do let's see do i want to do one more thing let's let's just let's see if we can add in a side effect because sometimes you don't want to just return um something to the to the client sometimes you want to actually just do something and then use the default uh the default behavior so i'm gonna again have to comment some of this stuff out unicorns are fine the unicorns are great i don't know about fine they're fantastic app.exception we're handler to we're going to have a starlit http exception async def custom http exception handler request exception print fstring omg and http error and we'll get the representation of the exception and then all we're going to do return await http exception handler request exception and we're going to have to import our http exception handler from from fast api exception handlers import http and we're going to import the request validation exception handler we'll add one more and then we will call it a day exception handler request validation error and we're going to say async def validation exception handler request exception print fstring omg the client client sent invalid data and we will say exception return a weight oh no i want to put that inside sorry about that return await request validation exception handler request exception and then we'll just say app.get items let's say blah items because i don't remember if i commented out the things that would end up being overwritten item id async def read items item id is an int if item id equals three raise http exception status code equals four one eight detail equals again nope don't like three otherwise return item id item id okay let's try this again that was a lot of typing i'm a fast typer sometimes only sometimes try it out three we got exactly what we anticipated getting but look we got this omg and http error if we go in here we're going to use blah items we'll say blah items and for foo again you remember we're not we're not handling this in a um in a plain text response we could have that would have been fine but all we're looking for right now is a side effect right now we're printing this out we're showing [Music] this client send invalid data one validation error for request and then it actually prints out the string representation of it this is good not necessarily for printing to your standard output but this you could use this for logging or something like that that's where this sort of thing would would be beneficial okay that is it now that was a that was a long video we made up for the very short video um of the last one so you know if you're watching in a playlist i apologize for the uh the lack of consistency in the next video we are going to get into path operation configuration a little bit more this is going to be more for organizing your your routes grouping things things like that really setting up some documentation using the the swagger docs uh a lot better you can see here it says default we're going to be able to kind of group these things into into different different groupings here so i will see you then
Info
Channel: JVP Design
Views: 9,265
Rating: undefined out of 5
Keywords: fastapi
Id: 8xkMFW3201Y
Channel Id: undefined
Length: 25min 29sec (1529 seconds)
Published: Thu Jun 23 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.