Now that we've done a bit of refactoring
and extracted this common "fetchJson" function,
it's time to go back to our original goal,
that was to have some more
fine-grained error handling here.
We only want to show a "notFound" page
if the requested product does not exist,
not for every possible error.
So to do that we need to provide more details
about the error that we throw in fetchJson.
And what we're going to do is
create a custom error class called "ApiError",
that needs to extend the built-in Error.
This class needs a constructor,
and here we can pass the "url"
and the "status" code,
because that's the most useful information
about a failed HTTP request.
Now, we need to call "super"
and pass a string, that's the error message.
Here we can show the "url"
and the "status" code.
Next we want to make the "status" available
as a member property,
so we can check the status when an error occurs.
And there are a couple of other things
that we need to do when creating a custom error.
For that I'm going to follow the example
in the MDN docs.
If the browser provides a "captureStackTrace" method
then we need to call it,
and we also need to set the "name" property.
So I'll just copy this bit,
and go and paste it into our code.
But our class is called "ApiError"
and not "CustomError".
I'll also add semicolons.
Ok. Now that we have this "ApiError"
we can throw it from "fetchJson".
But instead of this message,
as arguments we want to pass the "url"
and the "response.status".
And this way we are providing
more detailed information from here.
Now, let's make sure that
what we've done so far works.
Let's try loading a product that doesn't exist
And we get a not found page,
because in the ProductPage
we're still catching all errors here.
Let me comment this out temporarily
and re-throw the error,
so we can see what it looks like.
Ok, it's our "ApiError",
showing the URL and the status code,
that in this case was 404.
At this point we can,
first of all export the "ApiError" class,
then if an error occurs
when getting the product data
we can check if it's an "instanceof"
our ApiError.
And the class should have been auto-imported.
That's fine.
Now, if it is an ApiError
then we can check its "status" property
and only if we received a 404 from the CMS
then we want to show a "notFound" page.
But if it's a different kind of error
we'll just re-throw it,
and let Next.js handle it as an unexpected error.
So if we save these changes
we'll get a not found page for product "99",
because it doesn't exist.
While if we request a valid product "id",
we'll see the normal page.
Ideally we should test what happens
if the CMS is not available,
like we did a couple of videos ago.
But that means rebuilding the app,
run it in production mode, and so on,
so I won't do that again.
But feel free to try it if you like.
What will happen in that case is that
it will be a different kind of error,
so we won't show a not found page,
but Next.js will return a server error page.
Anyway, by creating a custom error class,
we can handle each specific error appropriately.