- [Maximilian] Now to conclude this section
about working with MongoDB and Node and Express,
I wanna highlight a specific limitation and issue
that exists in Express.js of which you should be aware.
When you have asynchronous route handler
or route middleware functions,
as I have it here, for example,
for getting a specific post by ID,
then whenever an error is thrown inside of such a function,
the default Express error handling middleware,
which normally catches errors for us,
will not become active.
Now because of that, you will actually notice
that if you will try to view a specific post
and you manually enter a wrong ID here, it crashes.
This entire server crashes
instead of showing us the 404 page.
The reason for that is that we don't even make it
to this part here because creating such an object ID
for which we're using a functionality exposed by MongoDB
will actually cause an error and throw an error
if we don't pass in a valid ID
that can be converted to such an object ID.
That's just how the MongoDB package works
when it comes to the creation of these object IDs.
Now, if an error is thrown,
normally the default error handling route
would become active.
This error handling middleware to be precise.
But since we're in an async function
and therefore in a function
that automatically returns a promise
because all async functions return promises,
that's what the async keyword does,
it wraps the entire content of the function
into a promise so to say,
because that's the case,
Express.js, because of its mentioned limitation,
does not catch this error for us.
To ensure that everything still works,
we have to do that manually instead.
We can use the try catch feature
I mentioned early in the course already.
Here, we can try a certain piece of code.
For example, we can try creating this ID
like this.
And if that fails,
we can catch the error and come up with some fallback plan.
So we could then actually change
the postId here to a variable
so that we can reassign it here if that should succeed
and then we can use postId down here
if converting had succeeded.
But if that should fail
because we, for example, passed in a wrong postId,
then we can catch the error manually and handle it manually,
and we have to do that because as mentioned,
the default error handling middleware won't become active.
Now, there are two ways of handling it manually here.
You can directly return the response you wanna return,
for example, that 404 page.
We can do that here.
And that is probably what we wanna do here.
But alternatively, if you wanna ensure
that the default error handling function becomes active,
you can accept a third parameter here in this function
and that's this next parameter.
Express.js provides this next parameter
for all the middleware functions
and the route handling function here, in the end,
is just a middleware function.
Next is itself a function that can be executed
and we can execute it to move the request
on to the next middleware in line.
Now, in these middleware functions
that we use in our routes setup here,
we typically don't wanna do that
because these route functions are the last step
in handling the request.
But if things go wrong, that's actually not the case,
then I want the request to move on
to the default error handling middleware.
And to ensure that this is the case,
all we have to do is pass this error object into next.
If we do that and then return
to make sure that no other code executes thereafter,
we will actually again reach
the default error handling middleware.
So if I now save everything and reload,
now I get the something went wrong page
instead of the server crashing.
Again here, that's probably not even what we wanna do.
We might instead prefer to just directly render to 404 page.
And of course, we can do that as well.
Now we get this page if I reload.
It's just important that you understand
that when you work with asynchronous code with promises,
you have to manually forward errors
to the default error handling middleware, as I showed you,
or handle the error manually in general,
for example, by setting your own response.
And theoretically, we should manually handle
all possible errors that could occur
in any of the other route handlers here as well.
For example, whenever we are converting some ID
to an object ID.
I'll not do it here to not clutter the code too much,
but you can do this as an extra practice.
And later when we build this main online shop project,
we will, of course, do it properly there
so that there you see a best practice project
from the ground up.
But here, I just want to make you aware of this limitation
and that in async functions,
you have to manually handle potential errors
that could occur because otherwise,
the server will just crash and we don't want that.
And therefore, that's now this project finished.
Now we added all these features we wanted to add
with help of MongoDB.
And now the data is stored in a real database,
in the MongoDB database to be precise,
and we saw all these core MongoDB operations
which I introduced you to in the last course section
in action in this course section now.
And therefore, now we got all the basics we need
to also use that a little bit later in the course
once we work on a bigger project.
Of course, as always, definitely feel free to practice this
even a bit more on your own.
Maybe try managing authors on a brand new page here,
build your own demo projects,
and of course also go through this
and/or the last section again
if some of the aspects covered here
should not be entirely clear yet
because we are now going to move on
and dive deeper into web development
in the next course sections.