Introduction to Error Handling in Nuxt
All right my friends, so we're making pretty good progress with the website. We have a lot of different pages: home, about, products, and then individual product details as well. Now, at the beginning, if we go to a page that doesn't exist, for example, /mario, then we're going to get the default Nuxt 404 page because we don't have a component called Mario in the pages folder, so we don't have a page for that. So we're getting this default page right here, which is an error page.
And likewise, if I go to /products and then go to a product that doesn't exist—for example, use ABC as the ID—this time we're not going to get a 404 page, but what we are going to get is basically a blank product details page because we can't fetch data for a product that doesn't exist. So in this case, we're just getting this kind of blank product details page.
Now in both cases, what I'd like to do is show a custom error page. So in the case of /mario, for example, instead of this default one, we would show our own custom error page. And in the case of this right here, instead of just showing them this blank page, again, we would show them maybe a custom 404 error page.
Creating a Custom error.vue Page
So the way we create custom error pages in Nuxt is dead simple. In the root directory, just create a new file called error.vue. So this is a Vue component, and much like our other pages, it's going to act as a page, only this time as an error page. I'm going to get this now instead of the default error page that we saw in the browser that Nuxt provides us with.
So in here, what do I want to do? Well, first of all, I want to basically just boilerplate this template. Let me go over here. And then I need to accept a prop into this component. Now, this prop is the error. So I'm going to say defineProps right here; we've seen this before. And then this can take in an array to say we want the error prop, like so.
Building the Error Page Template
Now we can use the error inside the template. Now, what I'm going to do is add a class to this first of all, just to style it a little bit. And that's going to be mt-7 to give it margin-top. max-w-sm and then mx-auto, so that's the margin-left and -right being auto. Text is going to sit in the center. And then also we'll give this a class of card, which is the custom component we created.
Alright, so inside this div, I want to output a few different things from this error. The first one is the status code. So let me do a p-tag first of all. Again, we'll give this some classes, so mt-7 with some margin-top, text-7xl makes it really large, and then also font-bold. Then inside the p-tag, we want to output a variable. It's the error.statusCode. So whenever we get an error in Nuxt and we're directed to this page right here, this error component, then we're going to automatically get this error object, and it's going to contain all this different information about the error. So for example, if we go to a page that doesn't exist, then the status code is going to be 404, and we're going to show that right here.
Displaying the Error Message
So now, down here, we're going to do another paragraph tag, and this time we'll give this a class of mt-7 again, which is margin-top, text-6xl, so a little bit smaller but still large. And then we'll just say, "Oops!" right here. And then down here, we want to output the error message itself. So I'll do a paragraph tag again with a class equal to mt-7, the margin-top, and then inside here, output a variable. It's going to be the error, but this time the message. So we automatically get a message property on the error as well, which we're outputting right here. All right, so that is pretty much it for now. What I'd like to do is save this and just test this out.
Testing the Custom 404 Page
Alright, so if we go to something like /mario, then we get this custom error page. We output the status code—remember that comes from the error object—then "Oops!", and then also the error message: Page not found: /mario. So this is going to happen now whenever we go to a page that doesn't exist. Let's do another one, /yoshi. You see right here: Page not found: /yoshi. So this is now replacing that default 404 error page which we saw before. Now, I know it doesn't look great, but you can make it better if you wish. You can add links, you can add other design features, entirely up to you.
Now I want to show you something else. If I go to /products and then / some kind of ID that doesn't exist, we're still not going to get that error page. And that's because, like I said before, it's not technically an error. We still show the page, the details page for this ID, because there's nothing in our application that's saying, "Don't." It's only kind of failing because we're trying to fetch a product with this ID, ABC, and the API is saying, look, we don't have a product with that ID. So we're just showing kind of like this blank details page. So what I'd like to do is...
Throwing Errors with createError
at the moment where we try to fetch a product, if that product doesn't exist and we get a bad response, then what I'd like to do is throw a custom error and then show that custom error page. So then we need to throw this error inside the products details component right here. So let's open that. And right here, we try to fetch the data, a single product, right? And what we want to do is make sure that that product has a value.
So I'm going to say, if (!product.value), then do something. So if the product doesn't have a value, then we're going to throw an error. So we say throw, and then the way we throw an error in Nuxt is by using a function they give us called createError, like so. And then inside this function, we pass an object to define the error. So we can give it a statusCode, so I'm going to give it a 404 to say, look, that doesn't exist, that page for that product. And then also we can give it a statusMessage, and then that is going to be Product not found. Okay, so this is the message we output on the error page right here. So when we throw this createError function right here, it creates the error and it shows us this error page. It passes in the error that we create right here as a prop to this page, and then we can output it in the page template. So let's give this a whirl.
Clearing Errors and Redirecting Users
Alright, so let's start by going to a product that does exist to make sure that still works. It does, awesome. And now let's use an ID for a product that we know doesn't exist, and we should get that error page, which we do. Awesome. So that's the status code that we set, then we get the error message that we set as well. Awesome. And this is going to be the same for any product where the ID doesn't exist. So if I do 1, 2, 3, 4, 5 here, that's not going to exist as well, and we still get that 404 error page. Awesome.
Now, there's one more thing I want to do, and that is to place a button down here so that when a user clicks that button, it's going to clear the error from the Nuxt application, and also we can redirect them then to another page, like the home page. All right, so let's start inside the error component by creating a button. And I'm going to give this a class equal to btn, which is the custom class we created, and then also margin in the y-direction, strength 7. And then inside the button, we'll just say Go Home.... And then also right here, we're going to add a click handler to it, so @click and set that equal to some kind of function. Now, I'm going to call this function handleClearError.
Okay, so what I'm going to do is create that function down here. So I can say const handleClearError and we set that equal to an arrow function. And all we're going to do is call a function built into Nuxt called clearError. And that's going to clear the error from the application. And then we can pass through an object as an argument where we can also specify a redirect path. So we can redirect to another page. In our case, I want to go to the home page, so just /. And that's all there is to it. So now when we click on this button, it will clear the error, and it will redirect us to the home page. All right, so if we go to a product that doesn't exist like this, we can now see this button. When we click on that, it's going to clear the error and redirect us back to the home page. Awesome.
Handling Client-Side Fatal Errors
Now, just quickly, one more thing. At the minute, what I've done is shown you when we request a page from the server, the code actually fires on the server to create this error and pre-renders that error page for us using this error component. Now, what happens if we just click on a link to a page that doesn't exist? For example, inside the default layout right here, what I've done is added an extra link at the bottom, which is to /product/abc. So now this code right here would be firing in the browser and not on the server. What happens in that case now?
Well, in a browser, if we click on this now to go to that product page for a product that doesn't exist, then we don't get the error page. But instead, we can see we have an uncaught error. So this is what happens when the error is created in the browser. We're not requesting the page from the server anymore like when we typed up here and pressed enter. This is in the browser. So we could handle this error, we could catch it and handle it on the front end and do something on this page. Or if we wanted to, we could show the error page, but to do that, we have to add an extra property to the object that we pass into the createError function.
So what I'm going to do right here is where we have this object inside createError is add a third property, and that's going to be fatal, and we're going to set that equal to true. And when this is set to true, it forces the application to show the error page. And now in the browser, if we go to the ABC product, then it's going to show that custom page, and then we can clear the error by clicking Go Home. Awesome.