Image

touring-vue-router

5 min read
Last update: December 19, 2021

Error Handling and 404s

There are three different kinds of errors we need to catch in our application, and we will have different results for each of them.

  • When a user tries to navigate to a page that doesn’t exist.
  • When a user’s network connectivity fails.
  • When a user tried to go to an event that doesn’t exist.

Let’s deal with each of these problems one at a time.

🛑 Problem: The Generic Not Found 404

Right now when I go to a URL that doesn’t exist I get a blank page with no information about what is going on.

https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F1.1611600265624.gif?alt=media&token=4a100779-6fc8-4354-894d-89ccc1c7e6eb

☑️ Solution: A Not Found Component

Let’s create a generic Not Found Component that we’ll redirect to when a path is accessed that doesn’t exist.

📃 /src/views/NotFound.vue

<template>
    <h1>Oops!</h1>
    <h3>The page you're looking for is not here.</h3>
    <router-link :to="{ name: 'EventList' }">Back to the home page</router-link>
</template>

Now we need to render this component when we go to a catch-all route, by updating our router.js file:

📃 /src/router/index.js

...
import NotFound from '@/views/NotFound.vue'

const routes = [
...
{
path: '/:catchAll(.*)',
name: 'NotFound',
component: NotFound
}
]

As you can see, we’re creating a path that catches everything that hasn’t matched a current route our NotFound component, and then we are redirecting to the 404 path when we hit our new catch-all route.

There is a reason we’re redirecting to our 404 page (rather than just rendering the component), which will become clear in a minute. Now when we load up a path that doesn’t exist, like /login, we get:

https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F2.1611600265625.gif?alt=media&token=8ac5d95a-8ff0-4a80-a960-50ada7088e11

Looks great!


🛑 Problem: What about when we try to view a non-existent Event?

Right now, when we go to an event that doesn’t exist, like /event/1233 we get a blank page:

https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F3.1611600271115.gif?alt=media&token=be2d2e09-a270-4a3d-a825-63353a7692df

A better solution would be to add onto our NotFound component and navigate the user there. Let’s try it!

☑️ Solution: Creating a 404 page for a Non-Existent Event

First off in the NotFound component, I’m going to add a prop called resource which will default to page so if this component is loaded without the prop, the text will read “The page you’re looking for is not here”. This way when an event isn’t found, I can send in event as the value of resource and it will read “The event you’re looking for is not here.”

📃 /src/views/NotFound.vue

<template>
    <div>
        <h1>Oops!</h1>
        <h3>The {{ resource }} you're looking for is not here.</h3>
        <router-link :to="{ name: 'EventList' }">Back to the home page</router-link>
    </div>
</template>
<script>
    export default {
        props: {
            resource: {
                type: String,
                required: true,
                default: 'page'
            }
        }
    }
</script>

Now I need to update the router, so this route takes a prop:

📃 /src/router/index.js

...
{
path: '/404/:resource',
name: '404Resource',
component: NotFound,
props: true
},
...

And now I can redirect the user here if the API request when fetching an event returns an error:

📃 /src/views/Layout.vue

...
created() {
EventService.getEvent(this.id)
.then(response => {
this.event = response.data
})
.catch(error => {
console.log(error)

this.$router.push({ name: '404Resource', params: { resource: 'event' } })
})
}
...

Now when we go to http://localhost:8080/event/123123123 we see:

https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F4.opt.1611600273597.jpg?alt=media&token=2bd46a92-14f2-468d-bdbc-cb5e8a781b17

Great! Now when people link to events which don’t exist we have a really nice looking 404 page. Users hitting this page is inevitable since our users can delete events.


🛑 Problem: Errors won’t always be 404

The only issue with this solution is that we’re assuming all network errors we receive are 404 errors. However, what if the user’s Internet just died or they’re on a super slow connection? We don’t want to give them a 404 error if their Internet dies, but that’s what’s going to happen right now, so let’s fix this.

☑️ Solution: A NetworkError component

We’ll start by creating a new component:

📃 /src/views/NetworkError.vue

<template>
    <div class="networkError">
        <h1>Uh-Oh!</h1>

        <h3>
            It looks like you're experiencing some network issues, please take a breath and
            <a href="#" @click="$router.go(-1)">click here</a> to try again.
        </h3>
    </div>
</template>

Notice how I’m using the $router.go(-1) method here to push the user back to the previous page which triggered the network error. We learned about this in our previous lesson.

Then we’ll add this to our router:

📃 /src/router/index.js

...
{
path: '/network-error',
name: 'NetworkError',
component: NetworkError
},
..

And lastly we need to check which type of network error we’ve encountered so we can push to the appropriate path inside our Layout.vue:

📃 /src/views/Layout.vue

...
created() {
EventService.getEvent(this.id)
.then(response => {
this.event = response.data
})
.catch(error => {
if (error.response && error.response.status == 404) {
this.$router.push({ name: '404Resource', params: { resource: 'event' } })
} else {
this.$router.push({ name: 'NetworkError' })
}
})
}
...

Now if our API server goes down or takes too long to return, our users will get a network error rather than just getting a webpage that loads forever! See below:

https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F5.1611600276047.gif?alt=media&token=27c57000-ddaf-4679-8013-f9a1a8e6aa04

⏪ Let’s ReVue

In this lesson we learned how to create a catch-all error page when the URL doesn’t match any of our routes. We then showed how to create a 404 Not Found page when the user navigates to an event that doesn’t exist, and then how to filter out those 404 errors from other network errors.