Man: In this video, we're now going to implement
the global error handling middleware that we
just talked about before.
So remember that the goal is to write a
middleware function, which is gonna be able
to handle operational errors like this one.
Okay, so when a user hits a URL that doesn't exist,
while we can consider that an operational error,
and we in this case handle it by sending back
this response here, right?
But again, the goal is to do that in one central place.
For example, we have similar stuff up here.
So all over the place here we have these snippets
here, which handle the errors.
So we have to strike etch block here,
and if there is an error, well, then we handle it
by sending that error to the client.
And so again, in the end, we want to get rid
of all of this and handle the error in one
central middleware.
And so let's now start by actually building
that middleware function.
And in Express, it's actually very easy.
Remember how I told you that Express
already comes with middleware handlers
out of the box.
So as always, we start by using app.use,
okay, and then in here we define our middleware function.
So, to define an error handling middleware,
all we need to do is to give the middleware function
four arguments and Express will then automatically
recognize it as an error handling middleware.
And therefore, only call it when there is an error.
And so just like in many other cases, this middleware
function is an error first function,
which means that the first argument
is the error,
and then we have request, response, and next.
So by specifying four parameters,
Express automatically knows that this entire
function here is an error handling middleware.
So let's now implement the code for this function here
and after that I will show you how we can actually
create an error so that this middleware function
is actually caught.
So two steps, first we create the middleware,
then in the second step we will actually
create an error so that this function will get caught.
And for now, let's keep it really simple here.
So all we really want to do in order to handle
this error is to send back a response to the client.
So res.status,
but now we don't really know which status code it is, right?
So for example, in this case here it's a 404,
but we have some errors here, which have other status codes.
Like we have a 400 for example for bad request,
or really all kinds of other codes.
And so we actually want to read that status code
from the error object, all right?
So when we create that error a bit later
in the second step, as I told you,
we will define this status code on the error.
So let's say status code,
and now I want to define a default here.
Because there will be errors that are not
coming from us because there are gonna be errors
without a status code, so errors that are not
created by us, but for example some other places
in the note application.
And I know that sounds a bit confusing for now,
but you will see throughout this section.
For now let's just really define this default
status code.
So we say that the error.statuscode is equal
to err.statuscode basically if it is defined
or the code 500, which means again,
internal server error, and so that's usually
the standard that we use.
And in the same way, we also define the status,
so let's say error.status is equal to error.status
if it is defined, and if not,
it's error.
So error, remember, is when we have a 500 status code
and if it's a 400 status code, then it's a fail.
So for example here in this 404 , status is fail.
And so now here we can then use that,
so error.statuscode, and then send some json,
so very similar to what we did before.
So we start with the status and read that from error.status
and the message will be coming from the error as well.
So err.message and I'm gonna show you in a second
how that err.message property here is created.
All right, but for now, this is our very simple
error handling middleware.
So very simple, but for now it works.
And so now the second step, where we actually
create an error.
And so let's do that here.
So right here in that function, which handles
all the unhandled routes, so let me comment this
one out here and instead we want to create an error.
So let's say const err
and it's a new error.
So we basically use the built in error constructor
in order to create an error.
And now we can pass in a string and that string
will then be the error message property.
So what we just talked about down here.
So that message should be this message.
All right?
And then it ought to say err.status
which is fail,
and then err.statusCode is equal to 404.
So that's what I mentioned before that we can define
the status code and the status on the error object.
And so that's exactly what we're doing here.
We're creating an error and we then
define the status and status code properties on it
so that our error handling middleware
can then use them in the next step.
But now, how do we actually read that next step?
So that next middleware.
Well, as always, we use next.
But this time we use next in a special way.
Because now we need to actually pass that error
into next, so if the next function receives
an argument, no matter what it is,
Express will automatically know that there was an error
so it will assume that whatever we pass into next
is gonna be an error.
And that applies to every next function in every
single middleware anywhere in our application.
So again, whenever we pass anything into next,
it will assume that it is an error, and it will
then skip all the other middlewares in the middleware
stack and sent the error that we passed in
to our global error handling middleware,
which will then, of course, be executed.
And so let's now pass in the error
which will skip again, all other middlewares
in the stack and go straight to this one.
Now in this case, there is actually
no other middleware in the middle, okay?
So it's really just the next one here,
but if we were to use next and pass in an error
somewhere else, then of course it will work the same.
And so let's now test all of this simply by
trying to access a route that was not defined.
And so that will then trigger all of this code here,
jump to the error handling middleware,
and then send back the response based on all
of this logic here.
So, here we still have our wrong or non-existing route
and let's start by actually calling this one,
which should still be working,
okay so just to confirm
that everything works just fine and it does,
and now this one.
And indeed we get can't find API slash tours on this server,
and so our global error handling middleware is
actually doing its job.
Perfect, that's the first step in really implementing
a way better error handling mechanism
in our application.
So we could now go ahead and try to implement
this kind of stuff here, everywhere in all
our handlers.
For example, over here in all of these functions
that we have here.
So replacing everything that we have here
with this kind of error.
But what I want to do for now is to actually create
our own error class.
So that we don't have to write all of this code here
and instead have a more like streamlined class
of ourself.
So that's a common practice, and so let's do that
in the next video.