.NET 6 - Web API Global Exceptions Handling 🌐 ❌

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello friends thank you for watching this video i am muhammad and today we're going to be discussing something really important when it comes to building any dotnet application which is error handling and in today's video we're gonna be discussing global error handling and how we can implement it within our web api we're gonna go through the process of creating a web api and basically creating a uh simple model conducting a database and then we're gonna be basically creating a global exception link middleware we're going to understand why do you want to build it there and how we want and why do you want to make it as a middleware and then we're going to see how we can actually implement different types of exceptions and then we can see how it will be able to catch those exceptions when anything happens within either in our controller our database and our services so on so forth so this video is going to be quite interesting one because basically it will build up on how we can actually create much more sustainable and durable web apis and another application if you like this video please like share and subscribe it will really help the channel as well if you'd like to support me please consider supporting me on patreon as well buying me a coffee now grab your cup of coffee and let's get started so let us discuss our plan for fork for today first of all what we're going to be doing is we're going to be creating an application we're going to be installing some packages we're going to be implementing a simple crud where we're going to be able to add create delete and update and then from there we're going to be implementing the global exception handling so basically when we added it's going to be implemented directly on our controller and basically subsequently any controller that we create or any implementation that we're going to be creating after that and we're going to see different types of exceptions so not found unauthenticated and handled error so on so forth it's gonna be multiple types that we're gonna be covering and this is really important to see how we can actually implement a single middleware for uh exception handling basically global exception handling and we can basically cover a wide range of exception that the system might generate and we're going to be seeing how we can actually implement our own custom exception if we need to as well so let's get started first by creating our application so inside our terminal here first of all we need to make sure that we have 1.6 installed we have the sdk available and ready for us once we have that let's navigate to our our folders and let's go to work learning dot net and let's create a new basically folder i think there's a error handling folder and let's create a new application dot not new it's going to be a web api and we're going to give it a name of global error handling or can call the global errors app something like that and it's gonna it's gonna take a few seconds to be completed and it has been already completed once that is done uh let's navigate to it and once uh let's do a let's see what's inside and let's do that build just to make sure that everything is building as it should be and we can see here that build has been succeeded and once we have that let's basically open the visual studio code perfect so now it's open in visual studio code let's zoom in a bit let's make sure that this is big enough i think it needs a bit more okay i think that should be fine okay so first things first once we have our application ready let's open let's remove this we don't need it let's open our terminal here and let's make this a bit smaller and i'm just going to do a dotnet build again just to make sure that everything is running great so once we have created our application and we have opened in visual studio code the next step is for us to install some packages and for the sake of this video we're gonna be utilizing with our cloud postgres uh database if you don't know how to set it up or how do you don't know how to connect it to our application and you wanna delve more deep into the postgres i'm gonna link a video here somewhere where you'll be able actually to go see a much more detailed video on how you can actually accomplish that but for now we're going to just uh assume that you already have a database setup it doesn't have to be postgresql any database server that you might have it will work uh it could be sql my sequel postclass mango uh any even non-sql database will work but for the simplicity of this video and the following so we're not making it a couple of hours long we're gonna be utilizing postgres so the first package that we want to install is basically the entity framework core so it's going to be.net dot not add package microsoft dot entity framework core and let's install this we can see this will take a couple of seconds to be completed great the next one is going to be as well.not add package microsoft dot entity framework core design perfect let's clear this up so we have a better view the next one is going to be postgresql so it's going to be not add package npsql dot entity framework core dot postgres let's see np sql and pdo i forgot the g it's npg sql let's try this and the last one is going to be entity framework tools so let's add this so dotnet add package microsoft dot entity framework core dot tools okay great so once we have done all of that now we can verify this by going to our global error app to see us approach and we can see here that we have all of our application that has all of our new packages has been installed successfully which is exactly what we need so just to make sure that everything is running it's always good to always try to do a dotnet build so it's going to be not built and we can see here build succeeded perfect so the next step for us is we need to start creating our model and this model is going to be responsible for utilizing entity framework so we can migrate to the database and once we have done all of that and we have it inside our database the next step for us is going to be basically building some kind of database application to be context and then we're going to be getting the controller and then we're going to be implementing the global error handling so let's create a new folder and it's going to be called models and inside our models because it's a sample application and because formula one is the best sport so we're going to be creating a driver's model so let's create a new class and we're going to call the driver.cs and let's make this.6 perfect and this is going to be a very simple model it's going to be public and id or actually just do it like this and id and string name so it's going to be driver name and we're just going to put and last one is driver number very simple so once we have created this basically nowhere that we have created our model the next step is for us is to create our application to be context and from there basically we can start implementing the migration connecting everything that we need so let's go into our root folder and then let's get a new folder we'll call it data and inside this data we're going to create a new class we're going to call it app db context and basically let us we want this and from here what we're going to be doing is basically we're going to be setting up our application db context so it's going to inherit from the dbcontext class now let's fix those references and now what we need to do is implement the constructor and this constructor here basically it's going to utilize the db context options and then it's gonna take up db context and we're gonna just gonna call it contact actually options and we're gonna pass it to the base one as simple as that if you wanna learn more about how we can actually implement uh db contacts how we can create unit of work uh or basically how you utilize entity framework core within.not i'm gonna link a video here where you can actually go and basically explore that uh but for now i'm just assuming you already know all of that so i'm just skimming over it but i highly recommend to go watch that video if you're not really familiar with how we can actually create all of this and why we are doing it like this so once we have done all of that the next step basically we're gonna be uh just assigning the themes so that the drivers table that we have created so we're gonna say public oops public oh i'll split it outside let's make this like this let's make it as a single line and then here let's make it public tv sucked driver oops driver and we're gonna call the drivers and it's gonna be get unset very simple and let's fix those references perfect so now we have our db context ready so once we have set up our db contacts we can see here that we are actually progressing fairly well within our application so basically now we have a model we have a db contacts next is we need to actually create our connection string connected to our application runtime maybe do a migration and then from there we can actually start implementing our controllers and so let's take it step by step so once we have done that the next step is let's open our app settings and inside our app settings what we need to do is we need to add our connection strings where basically we're telling our net application how it can connect our database so from here it's going to be we're going to call it sample db connection and basically this is going to be a user id equal i already know all of this my password is gonna be equal to one two three four five six seven eight and we're gonna put server is equal to localhost and from here basically we need to specify the port oops port which is going to be oops like equal to 5432 and then once we have that we need to put the database and the database it's going to be equal to sample db 1 and lastly we're going to put integrated security and this is always going to be true and then lastly once we have done that we're going to put pulling oops pulling equal through great so once we have done all of that and we were able to actually set up that our connections thing the next step is we need to go to program.cs and inside our program.cs we need to actually inject our application db context with the connection string here very simple builder dot services dot add entity framework core psql and then here we're gonna basically connect our adddb context and here basically we need to specify what is our application tv contacts and in this case gonna be app db context i think let's fix those references okay great and now we need to specify the options and we're gonna see here gonna put options dot use npg sql i think this also we're gonna just make this capital and let's fix those references and from here we're gonna basically utilize the builder dot configuration dot get connection string and then we're gonna just pass a sample connection and that should be it let's make sure we call it sample connection sample db connection okay it's a good thing we checked and let's put this here and now if we do not build let's see what's going to happen perfect our application is building and this is exactly what we wanted great so now that we have our program ready basically we have updated it with the latest uh configuration so we can be able to connect to our database next step let's do not build and then once we make sure that everything is running for running from there what we can do is we can implement the first migration and making sure that our tables are being reflected into the database and then what we're going to be doing is we're going to be creating some database services where we're able to actually add update delete and it is our database and there what we're going to be doing also is we're going to making sure that we have basically the application db contacts injection to those services and then we're going to be implementing the global error handling so let's do right now does not build we can see that our application is building successfully and then we're going to put dotnet ef migrations and because this is going to be the first one what we're going to be doing is we're going to put initial underscore migration and this should take a few seconds but basically in essence once this is completed it's going to create the first migration for us and then what we're going to be doing is we're going to put dot net ef database update and this should update our database with the latest changes perfect now if we open our database browser db beaver and basically let us just close this we don't need these and let's open our data ask connect our database postgres next let's leave all of those and let's see the database name i think it was called [Music] can't remember the name sample okay global errors so let's put this as a database name the username was muhammad and the password was one two three four five six seven eight and let's do a test connection perfect and now finish now if i should open this and take a look at my database and i should be able to see inside that i have my tables and i see here the driver they've been perfect so now that i make sure that my database has been created successfully the table has been migrated there the next step is for me to create the services that we're going to be able to communicate with my database so inside my root directory what i'm going to be doing is i'm going to be creating a new folder and this folder i'm going to be calling it services and it's going to be very simple i'm going to create first an interface and then i'm going to create a implementation of that interface so it's going to be i driver service the first interface the only interface actually and here let us just let's make it like this and basically in assets within this driver interface we're going to be basically implementing the crud operation so we're gonna put public let's make it back okay public task um what is what's the first one let's put i innumerable driver i'm gonna go to get drivers and let's fix those references perfect the next one is going to be public task driver let's put a question mark because in case it's not we want to return another result and here we're gonna put get driver by id and it's gonna take an end as an id then we're gonna put prop oops public excuse me task we're going to turn the driver after adding it so it's going to be add driver driver driver i'm going to sell out our driver right now and then we're gonna put another public task another driver and we're gonna say update driver it's gonna take a driver driver and lastly we're going to put another public task boolean and this is going to be simply for deleting the user at the end so delete sorry three driver and driver very simple oh sorry it's gonna be here and id okay great now that we have created our interface the next step is for us to basically create our service who's gonna be implementing this interface and implementing the connection to our database so inside the services i'm going to put the new class i'm just going to call the driver service and it's going to be a very simple class actually very simple implementation but let's see it in action we're just going to implement the i driver interface and here let's just do simple implementation of this implement interface perfect and the first things first is we need to actually connect our application db context into the service so we're able to actually utilize it so we're going to put the prop uh public read only db context underscore db context and let's fix this references here okay great now we need to create our constructor and we're going to inject this into the constructor so we're going to say app db context contact db context and here is going to be db context equal db contacts so this is very simple so the reason that we're doing it like this is to make it easy for us to directly inject our db contacts into our application there's another way what we can actually do is we can actually uh inject this inside our actually create a unit of work and basically basic once we create our unit of work we can directly inject all of the service that we want there that's a bit more complicated that we're trying to achieve here for the simplicity sake of this video what we're doing is we're directly injecting this inside our service itself but i highly consider if you i highly suggest if you actually want to build a long lasting or basically a much more complicated application to directly utilize the unit of work is it basically it makes the separation of concern much more better and it will allow you to have much more flexibility around your db context and basically your database structure and uh for this reason for the specific we're directly inserting it here but again if you're actually utilizing creating a much more bigger i highly suggest unit of work if you don't really know anything about unit of work i'm gonna link it here somewhere where you can actually watch a full video how you can actually implement unit of work when it comes to creating a web application or an a.not application.net core web application so now that we have injected our db context uh the thing is here the first one we're gonna be doing is adding the driver and then adding the driver is gonna be quite simple so let's check it's gonna be far result equal awaits underscore db contacts dot drivers dot add async and we're gonna pass the driver if i can spell today driver and then what we're gonna be doing is we're gonna put awake underscore db context dot save changes async and then what we're gonna be doing is var actually return result dot entity very simple straight to the point now for the delete driver uh let's do this one first because we can reuteralize inside the delete of the driver we're gonna put return await underscore db contacts dot drivers dot first or default and here we're just gonna make do a matching on the id itself so if the id matches we'll find it if not does not exist and why it's not happy let's see oh okay i need to make this async and yes i don't understand why vs code does this type sometimes does not work so we just need to add it manually using microsoft entity framework core so let's add it here using microsoft dot entity framework core and now this should work yeah it's happy so let's do the delete here so all we need to do is for uh found found or actually for our result uh driver let's put it like this get by id we're just gonna pass the id here and let's make sure that it has been awaited and once we have done that just put basically uh underscore db context dot remove and we're gonna remove the driver and it's telling us that maybe is it remove async nope remove and then what we're going to be doing is we're going to put db contacts dot saver changes async and let's make this as an awaitable and then all we need to do is put driver return driver uh not equal to null so if it's not equal to null we're gonna return through it means it has been deleted successfully else we're gonna be returning false and then let's see this one got drivers so that's also very simple what we're gonna be doing is we're gonna put return await underscore db context the drivers dot to list async very simple and the last one is going to be updating driver and this is also going to be a bit simple so for result equal underscored actually let's utilize that again await get by id and here we're gonna pass actually it's gonna be confusing things tv context and drivers dot update i'm gonna pass the driver very simply is there an update async nope so without any wait and here we're gonna put await underscore tv contacts to save changes async and then all we need to do is just return result dot entity and that should be it so right now let's do not build just to make sure that all of the code that we have added it did not break anything it did not change anything or basically we did not miss anything that might basically break our application so once we have done all of that now it's time for us to actually inject this service inside our program.cs so let's go here and basically inside before we can actually do the builder.build let's inject this and we're going to put build oops let's put this all the way at the back builder dot services dot scoped and the reason what we're doing here is basically we're injecting this uh service in a scoped way so for every single request which is coming in we're creating a new instance of this service rather than having it as a singleton where a single version of the service which is available for us if you don't really know anything about dependency injection don't worry i have another video which i'll be linking again here somewhere which we're going to be covering dependency injection in much more detail and the difference between scope transient and singleton so let's put i driver service and we're going to put a driver service and let's just fix those references perfect let's do another.net build just to make sure that everything is working as it should be okay great once we have done that the next step is going to be very nice and we're going to be creating our controller and basically let's create a new class and we're going to just call the drivers controller [Music] drivers controller like it is something that belongs to microsoft why they don't have better support for that application i don't know anyways that's a topic for a completely different day so let's copy this and let's make is this a bit better so this first is gonna be called set weather forecast it's gonna be called oops drivers controller we don't need this uh we don't definitely definitely don't need this so now we have like a very simple empty controller called drivers on we don't need this so this one here needs to be updated okay perfect so now that we have basically a very simple and empty controller that basically does not do oops don't need this which this does not do anything yet what we need to do is first of all we need to inject our service create some of the endpoints that we want and then we can work on creating our global error handling so first of all let's inject our service so it's going to be private read only i driver service i'm gonna call the driver service and let's add this and then here what we're going to be doing is i'm going to just inject it into my constructor so i driver service and then go to driver service and then let's just pass it here so driver service equal driver service perfect so the first thing first is let's just create a simple endpoint and this endpoint will allow us basically to interact with our uh application and basically either a delete update so we're just gonna build it as we go i will not uh we're not gonna do all of them right now just create one by one and we're just gonna see how it works excuse me so let's try it here so the first one is going to be the simplest one so it's going to be http got and we're going to call it driver just basically get all the list to get all of the drivers and for this one it's going to be public async task i action result and basically here we're just going to call it drivers list it's not gonna take anything it's not gonna process anything we're just gonna basically go to the database check all the drivers that we have and return them back to us we're gonna put for uh let's just select the return oops for driver list drivers actually equal await underscore driver service dot got drivers and i'm gonna do basically return okay and return the drivers it's very simple and let's add another one which is basically going to allow us to add the driver and understood the driver id so first of all let's do the add a driver it's going to be http post and we're going to call it add driver it's going to be public async task i action result driver and we're just gonna pass the driver as a driver very simple okay so let's see this perfect these this works or than visual studio code so now let's do a very simple var result equal await driver services a driver driver and then here what we can do is return okay oops okay and return result yep that should be fine and lastly let's get driver by id which is going to be an header http gut and we're going to call this get driver by id and it's going to be public async task i action results i will say get driver by id and it's going to be of type and we're kind of passing the end because this is uh we're going to be passing the id because that's what we're going to be doing the matching on and first of all let's do var driver equal uh what are we gonna do in here we're gonna put await driver service cut driverbot id passing the id that should be it and then we're gonna say if driver equal equal to null so that's one aspect that we're gonna be doing we're gonna say basically return not found we're gonna update this to a different different thing down the road but that for now that's returned not found and right now what we're going to be doing else we're just going to be returning okay and we're going to return the driver so this is a very simple implementation of an api endpoint and basically with the integration to our postgres database and be creating an application db context and we can see here that we have the different layers so we have basically the database layer we have the service layer and we have the controller layer and basically what we want to do here is we want to basically create a single error handling mechanism so in case there's a failure within any of those layers if it's a database failure if it is a service failure if it is a controller handling failure any of those our global exception will be able to capture it so we don't really have to redo the work on all of these layers so now that we have like a moderate crud three input cloud we still have to do the update but that's fine now it's now basically it's time to create our uh global error handlers and those global error handlers basically we're going to be creating it as a service where we can be able to inject it inside our middlewares and basically once we are able to inject it into our middlewares our application will be able to actually recognize this if there is something going wrong and once we actually the application is able to recognize that something is going wrong and something is not right it will be able to capture it and basically process it based on that error type and that's going to be the main goal so once we have done all of that now let's go back to our root directory and inside the root directory of our application what we're going to be doing is i'm going to be creating a new folder and this folder we're going to call it exceptions and inside the shop's exceptions folder i'm going to be creating a class basically i'm going to creating different classes and basically all of these classes they're going to be representing different types of error that i might have and there's a lot of different errors for now i'm just going to be covering some of the few basics one but you can basically expand it as much as you want and the first one we're gonna put bad excuse me request exception and let's fix this and basically here it's just going to be simply inheriting from the exception class and within the constructor what it's going to be doing is accepting a string message and it needs to pass the space message oops message so basically we're just inheriting from the exception global class we're creating our own bad request exception and we're building on top of that so that's the first one uh the second one is gonna be the uh not found so let's create a new class and i'm gonna say the key not found exception again similar to what we have done before we need to inherit from the exception class and then here i'm gonna create the constructor and it's gonna request string message and it's gonna pass this to the base class as a message great so now i have done that the next one i'm gonna create a um let's create a new class and this class we're gonna call it as simply as not found exception and this is not found exception it's not going to be any different so let's take this i'm gonna put exception and similarly to what we have done previously it's gonna be string message pass to the base message and that's it perfect and now the last next one is going to be not implemented exception so new class not implemented exception not implemented exception okay that's correct and then here is going to be exception again i'm gonna put here uh string message equal base message to us fix this oops and lastly let's add i'm gonna put unauthorized unauthorized exceptional access exception okay let's fix this and here exception and then lastly what we need to do is put string message and pass it to the base okay so now what we have done is basically we created five of the most generic exception types which is gonna be the bad request keynote found not found exception not implemented on unauthorized access exception so these are going to be the most common five exceptions that you might face with the new building with an api or any uh web application so right now although we have these five exceptions but we are not able to actually tie them together in any way so the next step for us is basically to have a middleware and basically this middleware is going to be able to intercept any exception which is maybe popping up and based on the exception type we're gonna basically uh do some implementations so in order for us to do that what we're gonna be doing is we need to go back to the root directory and inside the root directory here we're gonna be creating a new folder and basically this folder we're going to be calling it configurations and inside this configurations folder we're going to be creating the main global exception handler so let's create a new class and this is going to be called global exception handling middleware such a long name but that is completely fine so let's make this here let's close this let's add the semicolon here and perfect so once we have done that the next step for us here is to start to update this class so it will actually be able to process and be actually act like a service within our middleware so let's see how we can do that so first things first is we need to make a private not protected private read only request delegate and we're going to call it request sorry next and then we're going to create a constructor and this constructor basically is going to handle the request delegate the request delegate next and it's going to be something called underscore next equal to next so far so simple all we did is basically added the request delegate because this is what from the uh application pipeline that the but that nut will do when the application is running it's going to go through that pipeline and basically uh that pipeline is basically called the request delegate where we're passing it from one uh middleware to another again different video to go uh which cover this in much more detail so but this is just a quick overview so once that the request delegate jumps from one middleware to another and the reason we're doing it like this every middleware that we need to create should be able to handle that delegate request and should be able to pass it from receive it and pass it so the way it received is inside the constructor and at the end we can see how we can pass it to the next middleware and remember mr wales order is very very important so once we have done that the next step is we need to have an invoke so the invoke here basically it will emphasize that the middleware is going to be running and basically it's going to execute some stuff and then it will be us the middle where the action to the next middleware once the middleware is finished working our current mandible has finished working so public async task it's going to be invoke oops invoke and here what we're going to be doing is we're going to take the http context context and we're going to call it context from here we're just going to put try and catch exception ax and here we're gonna say await handle exception async context ex and this is this method right now that you have create doesn't exist so what we're doing here is we're going through the normal middleware that process that we have inside inside this in case there's an execution failure so let's say our any of the our three pillars has failed either the database the service or the controller have failed we have a try catch here so once it all pops up all the way back up and it fails there what we're doing is we're catching that error once we catch that error what's basically very simple we are passing that error that we have caught into the handle exceptions async method that we're going to be creating and once that method has captured the handle exception async it's going to be basically in essence verified or not verified it's going to be identified of what type of error it is once it has been identified what type of error it is we're going to be basically processing it based on that and basically return the response back to the user that we need to so here is going to be very simple it's going to be await underscore next i'm just going to pass the context so this is this is really a problem for us to understand so the request is coming in and basically once it comes in to our application it will go into the uh the controller then it go to the service and it goes to the database so let's say there's a failure on the service level something went wrong there and an exception has been thrown so it will pop up to the controller then from the controller it will pop up to the middle where that has invoked it and said inside inside that middleware what we're having here is we're going to having the catch request the catch sorry once we're catching it we're passing it into the uh we're passing it into the right method which is going to be hundred exceptions async method and then from there what we're doing is basically we are processing it so to make this a bit simpler let me just open this and to turn one second new private window and let's open it here let's go to the favorite website that everyone likes draw.io and this should be quite simple so the drought of ios open it up okay let's use it within chrome i don't know why firefox is not happy with it so and let's zoom in let's put on device create a new diagram and let's see what type of diagram do we want to create it should be fairly simple let's do a basic one and we'll call this global errors global error global so i'm gonna call it like this inside the downloads folder okay save so basically what we're gonna see if this is also being visible on the without being okay perfect so let's zoom in more okay so what we're letting let us explain what's gonna happen here so we can actually able to understand it in a much more visualized way so this is the user the user is here and basically uh the user did a request user so the user did the request and this request has basically flown from the user all the way to our application let's make it like this and for simplicity's sake i'm going to say this is my application i'm just going to put a line here and it means this has reached my application just for simplicity's sake so the user made a request and the request has came here so what what's gonna happen so the first thing is there's gonna be a lot of checks http checks that's gonna run in the background so basically the request is gonna come in it's gonna hit my application my applications verify it's gonna be a valid request so let's say here this is gonna be the http handler handler so once that http handler has been actually received and we can see that it has been accepted so the next step is it's going to go through the middlewares for example and we're going to have different middlewares which is going to be doing different stuff so right now we're just going to be focusing on them with the word that we're going to be having so since uh we said middleware is going to run one after another and basically they're going to be running as um it's going to be like running in one inside of another so it's going to be like a layered approach so this middleware has executed it's going to call the next one it has been executed it's going to go the next one it has been executed it's going to call the next one but and then once it finishes going to go back through the same ladder of the middleware that has been implemented so let's make this a bit bigger and let's imagine this is the first middleware that we're going to be doing and i'm just going to call this put here i'm going to put this like this is the first middleware and the next one and let's make this a different color so we're actually able to uh identify them so this is going to be the first middleware for example the http handler i'm going to have another middleware here which is going to be running inside of this one and this second middleware for example it could be let's make this a different color and let's copy this and just copy this this is going to be middleware number two and this middleware number two for example it can be the logs i don't know something like that so that middleware is now running the next step for us it's going to be the middleware that we have created which is going to be the global exception handling so let's take this and let's make this here and let's make this also a bit bigger and let's make this also a different color and let's copy this and here could be this is our new middleware which is going to be the global exception handling and let's take this and let's make this like this this is going to be middle number three and let's do add one more so we can actually see the full scope of this i'll add this here and let's make oops oops oops let's make this a bit bigger and let's make this a bit like this and we'll call this middleware let's say middle where four i don't know something that it's doing it in the background we don't really know the main reason that we wanna uh implement this here so we can see the flow of it so forth so this has the request had hit here the http handler which should be fine but once it has reached the http handler what happened is gonna be basically going from uh one aspect or basically one middleware to another in a layered approach so let me see if i can find like a nice arrow where we can see jumping in i think i saw it one time but if i'm not able to find it that's fine i think that's it yeah so what happened here okay let's make this okay so the middleware hit this one and then once that middleware hit the first hit the first one here let's make the middleware or the jump in a nice red color so after i jump into this one it will jump into the second one once and chop into the second one it will jump into the third one and then once that has been completed so this is gonna be the first step one two and three once it has been completed right now it's gonna start jumping back so let's put it this way and let's make it out so it's gonna be jumping outside so it's gonna be jumping outside the application something like that produce my drawing skills are not really up to the standard but it's going to be something around like that and then all the way out so we can see here so let's make this here as a see a different color let's make it this as a orangey color no it's not really okay let's make it this brown brown should be fine let's make this a brown and let's make this brown again so basically here what we're seeing is the middleware is actually coming in one by one and then basically it's exiting one by one and basically once we have let's say there's an error inside any of this middleware when there were four or anything uh so once there's an action a and an error happening anywhere it's gonna pop up to the middle where the middleware is gonna catch it and then it's gonna process it and this is really important for us to understand because uh it's a global exception handling so it's going to happen everywhere that we want so i think it's a better approach is to change this from here to here and make this the logs stud just to make sure it's a really high level but basically this is going to be the idea the request is going to come in it's going to hit the first middleware it's going to go to the exception handler it's going to go to all of the other middlewares once that's complete it's going to continue jumping back up so once that has been completed we're going to be able to actually see a much better or basically have much have a but better handling of our application so now if we go back here let us implement this method in order for us to actually see how we are able to handle those exceptions so it's going to be a very simple way to handle this it's going to be again all we need to do is going to create a new method and we're going to basically uh see how we can actually implement those error handling so first things first we're going to be creating a private static it's going to be task because it's going to be an async quest and we're going to put called handle exception async and this is going to take an http context we're going to call it context and it's going to take the exception itself ex and basically here what we're doing is going to put http status code because this is this is what we're going to be returning back to the user base in case there's any error we're gonna call status and let us add those references let's add them one by one this is the same name let's make sure okay so the next one is going to be var stack trace because this is really important for us to actually be able to get all of the error information pass it back to the user string dot empty and then we're gonna put string message just call it message as empty as well and then we're gonna put var uh exception type so basically here what we're doing is oops we're taking the exception that we have and we're trying to get an exception type x exception type equal ex dot get type and now basically what i did here is i just utilized whatever exception it has been sent back to me in order for me to get the type and lastly i'm gonna put if picks ups there's a typo here let's fix it if exception type equal equal type of not found exception so let us fix those references and let us understand what's going on here so because i got the exception type what i'm doing is i'm matching it to the exceptions that i have added previously here which is going to be the exceptions the bad request so and so forth because what i'm doing is i'm getting the type i'm matching it and based on that i'm going to be doing some analysis so right now for example or some processing sorry so let's see how we can do that so because i matched it to this i can say messages equal to say exception.message or it's going to be exmessage and then i'm going to say the status of this the http status i'm going to say http status code dot let's say bad request and then what i can say the stack trace equal exception ex dot stack trace so here we can see that i have much more control of what type of information i want to relay back to the user in case there is any errors and right now i'm taking a much more generic approach and general approach well it's a really live web application you don't really want to return your internal errors back to the user you need 100 much more better but for now for simplicity sake we're just returning the request as there is but let's say you are in a production environment and you have someone let's say a develo an endpoint which developers can consume it's much more better to send back a much more valid error where the and the user will be able to understand rather than just sending a stack trace of your api where basically we will give first the internal of how the application work which you shouldn't do that because basically it will give back more information and makes it easier for hackers to um or basically any suspicious behavior to uh take advantage of your api and you don't really want that and the second way is to make it much more user friendly so it will be much more easier for people to interact with and basically build api integration with so that's the first one let's do another one we're going to put else if exception type equal type of of not found exception not found exception and here let's say we're gonna put message equal e x dot message and we're gonna say status equal http status code status code dot not found not found and we're gonna put stack trace equal exception ex dot stack trace and let's see why it's not happy this one here okay so let's make this let's fix all of them i'll fix this error so let me do them for all so this one for the not found now let's say not implemented exceptions and for the not implemented it could be here for not implemented and this message could be the same yeah let's see what else another else so another not not implemented i think we have not found you we already added the not found so not found added so we have okay we have bad requests okay so we have bad requests we have the not found we have the not implemented and let's add the bad request not found not implemented now let's see keynote found and we can for example for the keynote font we can just make it as not found as well and for the unauthorized let's make it as unauthorized okay and lastly in case our error does not match any of this we just put an else and let's take this and this one here is going to be let's say the internal server error and let's leave the same as before and here once we've all done all of that we're going to put var exception results equal json serializer let's fix those references dot serialize new error oops error equal message and here for example we can see that here we are actually defining whatever we want to return back to the user so basically we're returning here a json which illustrate the error the message the status code and the stack trace and we're just going to turn here the stack trace and once that is done all we need to do is just attach the http response so context dot response dot content type equal application application forward slash json and context dot response dot status code whatever it has been come from before so we're just going to make it as end and we're just going to return the status that has been available for us and lastly we just need to pass back the request so return context dot write dot response actually dot right as write a sync list and then we're gonna put the exception results and this is exactly what we want so let's do a quick recap of what we have done here oh we still did not fix this and this is really important uh so let's go all the way up up up up up and let's add them here so we're gonna put a using statement so let's delete this did this delete this delete this and put it here using key not found exception equal global error up dot exceptions dot key not found exceptions so let's do them for the not implemented not implemented actually let's do it from here not implemented exception and let's do it as well for the unauthorized except access exception just take this just take this and here see why still not happy because for an if statement it needs to be a double equal and this shows you how early it is for me when i started recording this video and i haven't really woken up yet uh okay so i think that should be fine now let's do a dotnet build perfect this building so let us do a quick recap of what have happened here so basically in essence we created the middleware and then basically we added a try catch whenever the middleware is except of executing so in case there's an error here happening anywhere inside that middleware what we're doing is we're able to catch it and then once it catch it we have created a method called handle exception async and that method basically takes that error and analyze it and here basically we created the three variables that we're going to be populating and we got first the error the exception type so we can match it to one of the exceptions that we have created again this is our all generic exceptions there is much more you can actually implement yourself and what we're doing here is we're just doing matching f equal to that do this if equal to that do this if equal to that you do this so for example if at about request we're returning about request for example if it's not found not found not implemented not implemented so on so forth and unauthorized unauthorized and if there's anything which is not covered we're just returning an else with a generic uh internal server error message and then here what we're doing is we are basically serializing the request that we have the error with the stack trace and then we're returning it as json type to the user with the http status request of whatever the error was and then basically we're writing it back so we're stopping the request and we're sending it back to the user so that's in essence so now that we have created our middleware the next step for us is we need somewhere where we can actually inject it into our uh program.cs and that's going to be also quite simple to do so all we need to do is inside our configuration here we're going to be creating a new class and this class we're going to call it application builder exception sorry extension extension and this one is going to be fairly straightforward all we need is we're going to create the static class so we're able to inject our middleware so let's see what how that's going to work so first of all this class needs to be static static oops and then here all we need to do is just put public static i application builder application builder add application actually we're going to say add global error handling and we're going to put this i application builder because basically what we're doing here is we're taking the application builder that we're currently having and then we are passing it back so we're taking it injecting it and then we're passing it back so we're going to put this as a application builder application oops builder and once we have done all of that the next step for us is just do a simple lambda function which is going to be application builder application builder builder dot use middleware and we're gonna pass our global error handler global handling exception middleware and all we need to do is make it like this perfect so now that once we have done all of that the last step is we need to do is we need to go to the program.cs and inside our program.cs let's add it here gonna put up dot what did we call it uh where is it where is it it's called addi global error handler so let's add this here and let's fix those references and that's it and now let's do.net build perfect the application is building and now let's run it and see what happens so dot not run it's gonna ask me for my password perfect now let's go back to that web browser here and let's go to localhost 5268. so it's going to be local host 5268 why okay let's remove https redirection i don't really want this right now let's run this again it was localhost 5268 was it what was it yeah localhost 52684 swagger for index.html perfect so let's zoom in a bit and basically here we can see that we have our very simple api endpoint and basically we can see here that it has everything that we need so the three endpoint that we have uh let's delete this let's keep it so what i'm gonna be doing right now is i'm just gonna try to get a normal you know this is an ad i'm going to try to get a normal driver id so remember this is an empty database does not contain anything so right now if i just type 2 it should give me not found it's going to give me 404 error not found and basically it gave me this a generic error type so let's go back to our web api at our controller excuse me and let's open it up so what i'm going to be doing here is i'm going to update this so let's comment this out so it's just going to be throw new not found exception and we're gonna oops and we're gonna pass the message that we want let's and let's fix those references first and i'm gonna say here that the id is an invalid id for example or something like that so let's stop this and let's run this again it can ask no so right now if i come here let's look at the result so this is the original error that i received when i before i implemented my custom error handler so right now if i do uh exception execute sorry we can see that the error has been updated so first of all we can see that the error that i have created has been passed which is going to be the id is not a valid id and then here what happened as well is i was able to get all of the stack trays that i needed in order for me to have debugged ratio so again the stack trace is not something that you want to send back to your if if normal if developers are consuming it it's only good when you are developing your application but again this is a sample application so we can build it however however we want so that's one aspect so let's try another type of exception handling so let's say what i want to do what else did we implement so not found bad request so let's say here if let's say let's make this as a or for example let's just just for experimentation i'm gonna throw new bad request exception i'm gonna pass this is not a valid id and basically we're just experimenting here so that's the different types of error so the not found one we can see we got a 404 and we got this error here and now if i just rethrow a bad request let's execute this we can see that i the 404 converted to a 400 the error has been updated to a bad request the message for bad request has been updated and we can see i got the stack trace and from this you can see how powerful the global exception handling is where basically you have a single middleware handling all of the exceptions that you might have having full control of how you are sending the response back to the user having full control of how you can how you are actually processing if you want to add logs uh custom logs to your exception you can add if you wanna for example have custom logic to handle any exceptions you can also add it there if for example you want to [Music] have but much better performance you can do it from here and there's a lot more stuff that we can actually cover but the main item here is exceptions handling inside dotnet.6 utilizing global exception is a much more better way for us to handle it on a much more better scale and much more bigger scale when it comes to our application so for this let's do just a quick recap of what we have covered in today's video so first thing is we have basically created a new web api and then we basically created like uh uh models and then look at an application db context and then basically what we did is we have connected it to our database so all of this is just like a simple setup and then what we did is we have created a global exception we have created different exceptions we created a global exception handler middleware we basically injected into our program and then once we have injected into our program what we have done is basically we have uh just tested it out inside our controller to see how it works and basically you have experimented with it and again i really hope you were able to see the power of global exception handling because basically this will make your code much more structured and much more durable so if you like this video please like share and subscribe it will really help the channel and if you have any questions please put them in the comments down below and have a great day
Info
Channel: Mohamad Lawand
Views: 10,038
Rating: undefined out of 5
Keywords: dotnet error, dotnet error handling, dotnet global exception handler, .net 6, .net, api, beginner guide, step by step, c#, dotnet, dependency injection, coding, database, entity framework c#, entity framework core, entity framework, asp.net core tutorial, api security, jwt authentication, json api, dotnet security, microservices, .net core, asp.net core, web api, api logs, .net 6 logs, postgresql, postgres, postgresql dotnet core, postgresql dotnet
Id: fBXOgrZ3ZC4
Channel Id: undefined
Length: 74min 0sec (4440 seconds)
Published: Tue Sep 20 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.