-: So as I mentioned in the last video
there are three types of errors
that might be created by Mongoose
in which we need to mark as operational errors
so that we can send back meaningful error messages
to clients in production.
And let's now start by simulating these three errors, okay?
So the first one is when we try an invalid ID here,
so simply something like this,
and so Mongoose will not be able to convert this
into a MongoDB ID, remember that.
And so this is the error that we get right now,
and actually, here you can see all the kind of stuff
that we defined we wanted to see in productions.
So the entire error object, then the error message,
and also the complete stack, okay?
And so this is a perfect example
of an operational error.
So this is something that might very well happen,
and so we need to send back a meaningful response
in order to handle this error.
And this is a perfect example of an operational error
that is very likely to at some point happen to a client,
and so, we need to handle it as one, alright?
So, basically by sending a nice error message
instead of something like this,
which doesn't mean anything to any client, right?
Okay, so the goal here again
will be to basically mark this error as operational,
and create a meaningful message, alright?
But before we can do that, let's take a look
at the other two Mongoose errors
that we also will have to mark as operational, okay?
So, let's Create a New Tour,
and what I'm gonna do is to create a duplicate name.
So, let's just copy this one here.
And I think all the values here are correct,
so let's try this now.
And indeed, here we get the error that we already know,
which is duplicate key error
because we already have a tour,
or a document with the name of Forest Hiker, okay?
So again, this is an error
that is going to happen at some point,
and again, it doesn't have
a very meaningful error message, right?
And so again, we need to change that.
Then the third one is also kind of about validation,
and so let's do that here in Update Tour.
So, let's say that we want to have a ratingsAverage of six,
which we know is invalid, right?
Because we said that the max of ratingsAverage
could be five.
So let's see, and indeed,
we get this ValidationError, right?
So it's called a ValidationError,
and it has this errors object with all the errors.
Let's actually put another one here.
So let's say difficulty,
and then something else,
so one that's not easy, medium, or difficult,
and so now we get these two objects here.
Ones for the ratings, and one for the difficulty, alright?
So these are the three errors
that we're gonna mark as operational,
starting with this first one,
so basically, the CastError type, okay?
So, let's go back here, and we're gonna do that here,
again, because we only want to do this in production, okay?
In development, we don't care about any of this.
All we want to do is see our errors
so that we can basically fix them,
but in production, this is where we want to send
the meaningful error messages to the clients.
So, let's say if err.name
is equal to CastError,
and so that's how we're going to identify
this type of error here that we just talked about,
because it has the name of CastError, alright?
So if err.name is CastError,
well then we're gonna call a special function
that we're gonna create in a second,
which is called handleCastError.
And then I'm also gonna say here DB for database,
so that we know that this is related to our database, okay?
And this is how it's gonna work.
We're gonna pass the error
that Mongoose created into this function,
so just like this, and this will then return
a new error created with out AppError class, okay?
And that error will then be marked as operational,
because remember, all our AppErrors
have the is operational properties
set to two automatically, right?
So this will return an error, and so, let's save that, okay?
And so were saving that in err.
Now it's not a good practice at all
to override the arguments of a function, okay?
So error comes from this middle err function, right?
So, from here, and so instead of doing that,
I will actually create a hard copy
of that error object, okay?
So let, and I'm using let, and not const,
because we will of course reassign
a new error then, later here.
So, let's call this one error instead of just err,
which is the normal name of errors in Express.
And so again, we're gonna use our trick
where we use destructuring of the original error, okay?
And so, from now on, we will use this error instead of err.
So here, and here, and here.
Alright?
And so, let's now go ahead
and actually create this function here.
So let's put that up here right in the beginning.
Alright.
Try to remember that this receives an error,
and now I'm going back to just calling it err like this,
because again that's kind of the standard in Express.
And to start, let's take a look again
at the error object here, okay?
So here, we have the path, and we have also the value, okay?
So the path here is basically the name of the field
for which the input data is in the wrong format, okay?
And that value here is then this one,
which is, of course, the one that we past did, alright?
So, this might not only happen for the ID,
but really, for any field that we query for
with a value in the wrong format, alright?
And so, let's now basically create a string
that says that we have an invalid ID
with the value of this one in this case, alright?
So, it's path and value, okay?
So, let's create a message here,
and say Invalid err.path
is err.value.
Okay?
And so now, we simply return our own AppError.
Okay?
So just like I mentioned a couple of times by now, okay?
So AppError, and I actually have to include it here,
or to require, because I didn't do it yet.
So const AppError is equal to require,
and move one level up, then into the utilities folder,
and then the appError.
Here it is.
And so now, into or AppError, we pass in our message,
and the 400 status code, which stands for Bad Request.
Okay, and so just like this,
we transform the weird error
that we were getting from Mongoose
into an operational error
with a nice friendly message that
(chuckles)
an actual human can read, alright?
Okay, one last thing that we need to change here
is to also set this one here to error, okay?
And so, right now, if our error is CastError,
well, we will then pass the error into this function
which will return our AppError, so this one,
and that is the one that will then be sent to the client
using our sendErrorProd, okay?
And so, let's now actually try that.
So here, in our package.json,
we have this start:prod script, and so let's try that.
So, npm run start:prod, and I can actually auto complete
these npm script names using tab here in the terminal, okay?
And so, this will start a process
in production mode, basically, okay?
And so, let's now try this again.
So, if you're now doing this request,
we should get back the error message
that we just created, 'cause right now, we're in production.
And indeed, here it is.
So we have invalid, and then field name,
or actually the path name, and then the value
that we put in.
So if we try something different, then of course,
we get this, and of course,
also our 400 Bad Request code.
Okay, great.
So, this one is now handled.
In the next lecture, we will then take care of the next one,
which is for duplicate field names, alright?
So, see you then in a second.