Instructor: 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.