Error Handling With Express Flashcards
How can we catch all types of response methods?
We can use the all
method on the app
object.
How can we match any path in our app?
We can use *
to match any URL in our app.
Where would we create middleware to handle unhandled routes?
We want to create the middleware inside our main file.
What are operational errors?
These are predictable errors that we anticipate and handle in advance.
What are Programming errors?
These are bugs or mistakes introduced during development.
How can we implement a global error-handling middleware?
We use the app
method and pass in the arguments (err, req, res, next
).
What do we do inside our global error-handling middleware?
Set up properties to handle the status code, defaulting to 500 if not specified, and the status message, defaulting to ‘error’ if absent.
Next, we will send a response with the status code from the error object and a JSON object containing status
(set to err.status
) and message
(set to err.message
).
How can we call our global error-handling middleware?
We invoke next()
with our error instance as an argument. Calling next()
with an argument triggers the error-handling middleware we previously defined.
Where should we add the error-handling middleware?
You want to create its controller. Export the function, and make a middleware for it in the main file.
How can we create operational errors?
Create a class that extends from the Error
class. This custom class constructor accepts a statusCode
and message
. From the parent Error
class, we only inherit the message
property.
What does isOperational
mean?
Indicates that any error created with this class is an operational error. This distinction will be useful later when handling different types of errors.
What folder should the operational error class be in?
It should be in the utils
folder.
How can we refactor handling async errors?
We can remove all the catch blocks and create a helper function that will handle the errors.
Tell me what should the error helper function have?
It should accept a function as an argument. This function should return a function with req, res, and next passed in. This returned function should execute the passed-in function, chaining it with a catch method that passes the next method. This next method will automatically receive the error object.
How can we handle docs not found in our DB due to bad input?
We want to check if the document was returned. If the document was not found, we want to return a next function with the error class passed in.
Why should we create two separate errors for devs and users?
For users, we want to generate a friendly and easy-to-understand message. For developers, we aim to provide errors that are more detailed and useful.
How can we check if our environment is in production mode or development mode?
We use if
and else if
statements.
What should we do if our environment is in production mode?
Invoke a function, this function should receive two arguments. The error object and response object. This function checks if our error is isOperational
if so, it sends a message, or else it sends a generic message.
Why should we check if an error is an operational error during production?
This is because some non-operational errors can send error messages that can leak information.
How can we handle an invalid database ID?
We want to check if the error name is equal to CastError
. If it is, we want to call a function named handleCastError
.
What should we do before working with the error object in our production environment?
Create a copy.
What will be in the handleCastErr
function?
In this function, we will pass in a copy of the error object. Inside, we will create a message saying invalid err.path
and err.value
. This message will be passed into our AppError
class, which handles operational errors and marks them as operational errors. We also want to pass in 404
for a bad request status code.
How can we handle duplicate errors?
We want to check if the error code is equal to 110000
. If it is we want to create a function that will return the new error.
How can we handle validation errors?
We want to check if the error name is equal to ValidationError
. If it is, we want to create a function that will return a new error.
How can we fetch all the validation errors?
To get each error, we use Object.values
and pass in err.errors
, which will put every object into its own index in an array. We can then loop through this array and return a new array containing each error message, and finally, join them together into a single string.
What are unhandled rejections?
They are promise rejections that are not handled.
How can we catch them?
Use the on
method found on the process
object. Inside, we pass in unhandledRejection
and the err
object we get from it.
What do we do when we have an unhandled rejection?
We want to shut down our app.
What are uncaught exceptions?
They are errors in our synchronous code. Such as calling an undefined variable.
How can we handle uncaught exceptions?
We need to use the on
method on our process
object. Inside, we pass in uncaughtException
and the error object. We handle this similarly to how we handle unhandled promise rejections.
Why do we need to close the app if we have an uncaught exception?
We need to close the app because our Node app is in an unclean state.
Where do we want to handle our uncaught exceptions?
We want to create this process at the very top of our file.