‫Let's now make some more use
‫of our AppError class
‫business adding a couple of 404 errors
‫and some of our tour handler functions.
‫Now just one thing that I wanted to say
‫before we actually implement these 404 errors
‫is that of course we could have used the catchAsync function
‫also in our router, okay?
‫So, let me show you how that would work.
‫So, here in TourRoutes,
‫I could have wrapped this function here
‫into catchAsync just like this
‫instead of doing it right in here in the controller.
‫So, here where I did it in fact, right?
‫And that would have had the exact same result
‫but I didn't do it this way
‫because like this, I have to remember
‫which of these methods here
‫is actually an sync method,
‫okay, so that only on those
‫I actually add the catchAsync function, right?
‫Now in this case, actually all of them are async function
‫and so, that's not really the matter here in this example
‫but there will be some examples later
‫where not all the handlers are asynchronous functions
‫and so, in that case,
‫I would really have to remember
‫which of them I have to wrap into catchAsync
‫and which ones not
‫and so, in doing it in the controller
‫is much easier because simply each time that I'm writing
‫an async function here,
‫they already know well,
‫I need to wrap it into catchAsync.
‫Okay.
‫So, I'm not doing it here,
‫I just do it like I showed you in the last video.
‫Okay and actually I once run into a bug
‫that was really hard to find
‫because I actually wrapped a function
‫that was not async into catchAsync
‫and so that we really not working
‫and I couldn't figure out where the bug was
‫and wasted a lot of time on that one.
‫And so, since then, I no longer put catchAsync here
‫but really close to where I actually need it,
‫so close to the code that is actually asynchronous.
‫Okay and with that being said,
‫let's now implement some 404 errors here.
‫All right, so I wanna start
‫by showing you again the example
‫that we did in the last video.
‫Okay, so we tried to get a tour
‫for this weird ID that does not really exist
‫and the error that we got
‫is that basically Mongoose
‫could not convert this string here
‫into a valid ID for MongoDB.
‫But what happens when we actually use a valid MongoDB ID?
‫So, for example, let's, yeah,
‫let's copy this one here,
‫okay, and this one of course will have a result
‫and so, let's just slightly change it,
‫so for example, changing this to zero here
‫will still be a valid ID,
‫so it looks like this
‫and it looks exactly the same as before,
‫I just changed one number
‫but this ID will probably not exist.
‫And so, let's see what we get then.
‫And indeed, now our result here is null.
‫All right, and so, that's not really what we want, is it?
‫What we want here is to show a 404 status code in here
‫and say that this tour was not found.
‫Okay and so, let's now use orAppError class
‫in order to implement that.
‫Just keep in mind that the tour
‫that we get back here is null, okay?
‫So, null that we can now test for.
‫So, if we go to our getTour handler,
‫let's now implement if there is no tour
‫and in that case we will create or error
‫and this here works
‫because if there's no tour,
‫it will be null.
‫Remember and in JavaScript, null is a fallacy value,
‫so a value that will convert to false here
‫in an if statement.
‫Okay, and so, if there's no tour,
‫then tour is false
‫and then not false is of course true
‫and so, that's then how we enter this if block.
‫So, what do we want to do if there is no tour?
‫Well, we want to create next with an error.
‫So, in order to jump straight into or error
‫and linked middleware.
‫So, we do new AppError
‫which si not available yet, we still have to import it
‫but let's use it here right away.
‫Okay, and then let's just say
‫No tour found with that ID.
‫And then a status code remember
‫is the second argument is 404, all right?
‫Now one last thing that we need to do here
‫which is to say return, okay
‫because we want to return this function immediately
‫and not move on to the next line
‫which would be this one
‫and which would then basically try to send two responses
‫and we did already run into that error before,
‫so I'll hope you'll remember that
‫and that's the reason why we always need return here.
‫Okay, let's now go ahead and quickly import the appError
‫and that's similar to this one here,
‫so let's just duplicate.
‫Okay, and here it's actually with a capital A.
‫All right, give it a save
‫and let's now try it again
‫and now indeed no tour found with that ID 404.
‫Perfect, so exactly what we wanted.
‫Oh and you also saw that we have the failed here.
‫Okay and so that comes from or class as well.
‫Great, so that works and so I really hope
‫that by now you understood exactly how all
‫of this error handling now works.
‫Okay, so again we create an error
‫and we then pass that error into next
‫and as soon as next receives something,
‫it assumes that it is an error
‫and it will jump straight
‫into the global error handling middleware
‫which will then send the response for us, okay?
‫So, let's copy this one
‫and put it in all the other handlers
‫that query documents based on the ID.
‫So, not create tour but update a tour, okay?
‫And so, here the same,
‫if we're trying to update the tour
‫that does not exist,
‫it will then give us the exact same error.
‫Finally of course the same with delete.
‫And now you see that ESLint gave me this error here
‫and so, that's because this tour is not defined
‫and in this case, ESLint really saved me here
‫from creating this bug.
‫Right?
‫So, again without ESLint,
‫I would have probably just pasted it here
‫and called it a day
‫without even noticing that tour is nowhere defined
‫inside of this function
‫but since we installed this really valuable tool,
‫I can now go ahead and fix it.
‫All right, so up until this point,
‫we simply awaited this delete instruction here
‫and didn't save the result of it
‫and that's simply because we didn't need it.
‫Okay, but right now we actually do need it
‫because we want this tour variable
‫in order to verify if there actually is a tour or not.
‫So, very easy, const tour
‫and then equal to that result,
‫give it a save and then the error is gone.
‫So, great.
‫ESLint at work, all right?
‫Now maybe you noticed that I did not add this 404 error here
‫in this getAllTour handler.
‫So, why did I did that?
‫And so let me explain you why.
‫So, when there is zero results found,
‫for example, there are no results matching for a filter,
‫or because the page was requested
‫that doesn't exist, then of course we could consider sending
‫a 404 error and saying that the data
‫was not found but in my opinion
‫and also the opinion of other developers,
‫that is not entirely correct in this request
‫because there was not really an error.
‫I mean, the request was correctly received.
‫The database correctly searched for the tours
‫and found exactly zero records
‫and so, these zero records are exactly
‫what we're gonna send back along with the 200 HTTP code.
‫All right, so again I consider
‫that there cannot really be an error
‫when a user requests all the tours
‫unless of course there is some failure in the database
‫or something like that.
‫But in that case, Mongoose
‫will then automatically throw an error.
‫Right, which then in turn is gonna get catched
‫by our or catchAsync function
‫and as you already know,
‫handled in our global error handler
‫and as you already know,
‫handled in our global error handling middleware.
‫All right, so I've said these words so many times by now.
‫Anyway, I hope that made sense
‫and so, yeah, let's now move on.