Skip to content

Instantly share code, notes, and snippets.

@benjaminrichardson-ms
Created June 8, 2019 12:34
Show Gist options
  • Save benjaminrichardson-ms/d0d1f80ca41d39dccbad59fa20621104 to your computer and use it in GitHub Desktop.
Save benjaminrichardson-ms/d0d1f80ca41d39dccbad59fa20621104 to your computer and use it in GitHub Desktop.

Today I was putting the final touches on a Nuxt.js application and my aim was to set up some nice looking error pages that are other than the default Nuxt 'server error'. I ran into trouble because I had a few misconceptions about how Nuxt handles errors, and what features you get out of the box to help with this.

Naively, I thought that Nuxt would do everything for me

One of the reasons I love Nuxt is because of all of the features you get out of the box. But errors are one of those things, where no application can guess what you want to happen when certain situations arise and it all starts going wrong.

It starts to get tricky even more when you are dealing with other technologies like Axios and it's default interpretation of certain error codes, for better or for worse.

What types of errors am I trying to handle?

Firstly, I am writing an application that heavily uses Nuxt for the server side rendering capabilities it has. Every page I have must be able to be generated on the server to be as SEO friendly as any standard web page.

When writing lots of code that will all be executed on the server, you will likely run into the first kind of exception/error very quickly.

Nuxt Server Error

The Nuxt Server Error page

When you get your data for your site from an API, using a library like Axios, depending on what you are retrieving you may end up with various response codes from your request. For instance, my API returns a 404 Not Found code if your specific query has returned no results. You are still getting a response, and a message telling you what has happened, but this will trigger an exception in Axios. If you do not handle this, you will get the error page as shown above.

One important distinction to make is when you are running your application in npm run dev mode over a production npm run build mode, then you will see errors differently.

Nuxt Error In Dev Mode

Nuxt error while in dev mode

So that pretty much sets the scene, when you are in SSR mode and you get an error, it all goes south pretty quickly. So when this happens, what can do with the tools Nuxt gives you.

What got me confused

Most of everything you need is in the Nuxt Error View section of their documentation. This gets you started, but I still got confused around a few parts.

Thinking that Nuxt would show my error page for any unhandled exception

My first thought was that I was setting up a page that would replace the default Nuxt Server Error that I showed above. So I created the layout layouts/error.vue and populated it with the data snippets and template given in the Nuxt documentation. Rebuilt, I hit refresh on my page I was generating an error on....then nothing had changed.

What was wrong? Was my code wrong? Was something wrong with my Nuxt instance? Oh no, does Nuxt not actually handle errors well?

Well, what I had missed was this page about the Nuxt error handling method. Here it became clear that the Nuxt Error View is not about handling errors for you, but it is more about giving you a place you can direct your application to when things start going wrong.

Ah ha!

Once I knew this, I started to test this out in my app. If I call the error method that is available in the context then I should see the result I am after.

{% highlight javascript %} export const actions = { async nuxtServerInit ({ dispatch }, { app, query, route, error }) { const handle404Error = e => { error({ statusCode: 404, message: 'No products found' }) // Fire the Nuxt error function } ... {% endhighlight %}

From my store/index.js

Success, when I simulated a 404 on my API call, I was shown the error template that I had set up by calling the error method shown in the example above.

With this new success, I tried this out in another page I have in my app.

I redirected, but it did not work?

I redirected, but it did not work?

This new error made me question what I had learned up until now. I had called the error function in the same way as the previous page, but now it wasn't working. After a bit of digging around, I realised how the calls really work.

Ok, I think I have it now

There is a hierarchy that I had to figure out. The most important thing to know is that errors on the server take the most precedence over anything else. Not that they are more important, but they stop the execution of the Nuxt application. As a last resort, Nuxt can throw the Nuxt Server Error page. By this point, your Nuxt app has stopped executing. It has a static page it will return to the browser as part of the Express request. There is no Nuxt magic at this point either so you cannot call for other resources or reference your Store or the error that caused this in the first place.

Everything finally came together for me when I realised that the Nuxt framework does not handle errors for you, but it allows you to handle knows error states yourself whether your app encounters an exception on the server or on the client.

This means that when ever you are running commands that can cause an exception, you must make sure you are going to catch and handle the exceptions. In my previous example where the I was catching my initial exception, I was actually missing the subsequent exceptions caused by the lack of the data I was expecting. Because of this, the Nuxt error function was never able to fire properly in the Nuxt execution cycle. Hence, I was still getting the Nuxt Server Error rather than my custom error page.

So what to learn from all of this?

After figuring out all of my trouble, I now know my priorities:

  1. In the JS code, all possible exception must be handled. If you get an uncaught JavaScript error, then Nuxt will crash out of executing even if the exception occurs after you call error().
  • If your error can be silently handled, eg. no products returned from my API, then handle the 404 status code using a .catch() block. In my case with my API 404, I populate my product array with an empty array where my template knows what to show when the array length is zero.
  • This also mean any functions that can generate exceptions, like an Axios call, should be in a try/catch block.
  1. Once the exception has been handled, if necessary I can display the Nuxt error view to give the user some kinds of options for how to proceed. eg. Try again, or goto the home page
  2. If there is an exception that I was not expecting or cannot handle, eg. the API is down and did not respond, then I can call error from the catch block in my nuxtServerInit function, or in any of the async function where the Nuxt context is present.
  • I just need to make sure the lack of data from the API does not cause subsequent exceptions from undefined variables or type errors.
  1. After this, the Nuxt Server Error page should never been seen again!

Now that we know how to deliver a custom error page when it is needed, we can concentrate on creating an experience that gets our users back on the path they need to be. Given we have the full power of Nuxt in the custom error view, there should be no shortage of helpful suggestions we can give our users.

BONUS: You can actually customise the default Nuxt Server Error page

As a side note, I found there is a way that you can actually customise the Nuxt Server Error page, this is not really a feasible method for handling most errors, but it is still worth a mention.

In your nuxt.config.js you can overwrite the template that is used to display this page. More info on replacing the contents of the error page here. Going one step further, you can overwrite this entire page using a method where you create a new file app/views/error.html in the root Nuxt application directory. Again, I would recommend against this as a 'solution' as by this point you are fully out of the Nuxt framework, and you are essentially coding a static HTML file. Can you try to render {{ this }} to see there is something kind of happening but it is as good as static ;)

For me, this approach does not work as I need to pull my main navigation contents from an API, and feed it into components. If I cannot do this (because I am no longer in the Nuxt framework), then it is not viable for my needs.

References

Change the Nuxt.js server error page

Custom Error Pages with nuxt.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment