‫In this video, we're gonna implement some logic
‫in order to send different error messages
‫for the development and production environment.
‫So right now, we're sending this same response message here
‫basically to everyone, no matter if we're in development
‫or in production.
‫But the idea is that in production, we want to leak
‫as little information about our errors
‫to the client as possible.
‫So in that case, we only want to send
‫a nice, human-friendly message
‫so that the user knows what's wrong.
‫On the other hand, when written development,
‫we want to get as much information about the error
‫that occurred as possible, and we want that
‫right in the error message that's coming back.
‫So we could log that information also to the console,
‫but I think it's way more useful to have that information
‫right in postman, in this case.
‫So, we already know how to distinguish between
‫the development and the production environment.
‫And so, let's do that.
‫So if
‫process.env.node_env
‫is equal to development
‫then we want to send one type of error
‫and if we're in production,
‫then we want to send a simpler error.
‫Alright.
‫So equal to production.
‫Alright, so let's grab this one,
‫so again, when written development,
‫we want to get all the information that we can.
‫So that's also print or respond with the error stack here.
‫So err.stack, and then let's also print
‫the entire error also.
‫Let's say error, and set it to up okay.
‫Then on the other hand,
‫let's now copy this again.
‫When we're in production, we don't want the stack
‫and we also don't want the complete error.
‫So really just the status and the message.
‫This here looks kind of messy,
‫so let's export these into their own functions
‫and also because we're actually gonna add a lot more code
‫down here, in this else branch.
‫It's a bit cleaner to have these into
‫their own separate functions.
‫So let's say const
‫send error for dev
‫and that function should then receive the error,
‫and we also need to pass in the response subject.
‫That is because that's how we can actually
‫send the response, right?
‫So we need the response subject in order to be able to
‫run this code.
‫Here we're just gonna call
‫send error dev
‫with the error,
‫and the response.
‫Then down here,
‫we're gonna have
‫send error
‫production,
‫the same arguments.
‫And then here, the same.
‫So that was easy, let's now take it to the next level
‫and talk about operational errors again.
‫For that, let me open up the app error class
‫that we created, and let's remember that we mark
‫all the errors that we create,
‫using AppError is operational set to true.
‫So all the errors that we create ourselves
‫will basically be operational errors.
‫In fact, it's only these operational errors
‫for which we want to send the error message
‫down to the client.
‫At least in production.
‫So when we, on the other hand, have a programming error,
‫or some other unknown error that comes,
‫for example, from a third party package,
‫we do not want to send any error message about that
‫to the client in production.
‫And so that's no use.
‫This is operational property here in our error controller.
‫Remember how I already talked about doing that
‫by the time that we created this class, right?
‫Let's now come here to send error production
‫and do that test.
‫If error.isOperational
‫only in that case we actually want to send this error here.
‫In all the other cases,
‫we are simply gonna send
‫a very generic error message to the client.
‫So let's say, res.status
‫and we're simply gonna send a generic 500 code
‫and then json.
‫The status will be error.
‫Then let's just send a generic message, saying
‫something
‫went very wrong.
‫So doing something like this is very standard procedure.
‫Let me actually comment out some of the code here.
‫So this is an operational error that we trust.
‫Here we want to send a message to the client.
‫But in this case here,
‫we have an unknown error,
‫and so we don't want to leak the details to the client.
‫So we're just gonna send this message then to the client,
‫and also for ourselves.
‫For us developers, we want to know
‫that this kind of weird, unexpected, unknown error
‫occurred and we're actually gonna log it to the console.
‫We'll first log the error,
‫and then send a generic message.
‫Let's just say, console.error,
‫so this is a bit like console.log,
‫but it's really specific for errors
‫and I believe the output will then look a bit different.
‫So error, let's add some emoji here to make it visible
‫in our logs,
‫and then log the error as well.
‫Now there are real logging libraries on mpm,
‫that we could use here
‫instead of just having this simple console.error,
‫but just logging the error to the console
‫will make it visible in the logs
‫on the hosting platform that you're using.
‫I think that for now, in this kind of simple application,
‫that is enough.
‫For example, we're gonna use Heroku
‫by the end of the course to deploy our application.
‫Then when an error like this occurs,
‫it will be logged to the console.
‫In the Heroku platform, we then have access to these logs.
‫We can keep looking at these logs, and then in there
‫we're gonna find these unexpected errors
‫so that we can then fix them.
‫Right now, we're actually already building
‫kind of sophisticated and real-world
‫error-handling mechanism here.
‫So let's quickly recap what we just did here.
‫We're distinguishing between errors in development
‫and in production.
‫When we're in production, we send the error
‫using this function here,
‫which will then send as many details as possible
‫to the client,
‫so that we really get all the information
‫in order to get rid of the bug.
‫If it's a programming error,
‫or if it's an operational error,
‫then we still really want to see anything that's going on.
‫When we're in production,
‫which is arguably the most important part
‫of our application, then we distinguish
‫between operational errors,
‫so errors that we know and trust,
‫and to other errors, that might be kind of unexpected.
‫If the error is operational, so for example the user
‫tried to access a route that doesn't exist,
‫or tried to input invalid data,
‫all of these are operational errors.
‫Then we can send appropriate error messages,
‫for the client to know what went wrong.
‫On the other hand, we have these unknown errors,
‫or unexpected errors, and in that case,
‫we very simply say, something went wrong.
‫Then log the error also to our console,
‫so that we know that it happened and can then fix it.
‫Now in order for this to work,
‫there is something really, really important
‫that we need to do.
‫Right now there are errors that are, for example,
‫coming from MongoDB, which we do not mark as operational.
‫In this case, they would right now simply be handled
‫using this generic error message here.
‫For example, a validation error.
‫Right now, that's an error that's coming from MongoDB
‫and not from our own app error class.
‫We do not create these errors by ourselves.
‫Again, they are right now not marked as operational,
‫but we of course need to mark them as operational
‫so that we can then send the appropriate error message
‫back to the client.
‫In the example that I was just mentioning,
‫that the input data is invalid.
‫There are two or three other errors that we need to mark
‫as operational ourselves.
‫So we will do that
‫down here.
‫So in this else block,
‫we will do that over the next couple of lectures.