How do you handle errors when Nuxt's SSR runs into an error?
Currently i am using error()
handler but it doesn't work in the production?
This is the example of my Nuxt app.
asyncData
async asyncData({ store, route, error }) {
return store.dispatch( NAMESPACES.USERS + ACTIONS.GET_DETAIL, userId ).then(response => ({
data: response,
})).catch((e) => {
error(e)
})
}
error.vue
<vis-container>
<vis-row class="error">
<vis-col md="8" class="error__component">
<component :is="errorPage" :error="error.statusCode" />
</vis-col>
<vis-col md="8" class="error__contact">
<p class="error__contact__title">{{ $t('error_page.question') }}</p>
</vis-col>
</vis-row>
</vis-container>
</template>
<script>
export default {
props: ['error'],
components: {
NotFound: () => import('@/components/error/NotFound'),
InternalServerError: () => import('@/components/error/InternalServerError'),
},
computed: {
errorPage() {
if (this.error.statusCode === 500) {
return 'InternalServerError'
}
return 'NotFound'
},
},
}
</script>
This answer is only relevant for SSR mode.
There are different possible type of errors. I will provide here info about 2 types of them:
fetch
hook)Errors handling for dynamic routes [Option 1]:
According to Nuxt docs about lifecycle there is a special validate
hook. It's main purpose to validate dynamic routes parameters.
Here you can find more detailed description, but in general you need to provide validate
implementation which supposed to return true
when params are valid and false
when they are not.
In case of false
nuxt will return 404 response with default error page (you can also throw expected or unexpected errors during validate function execution as well as customize default error page).
Important note here:
This method takes the context object as an argument.
Errors handling for dynamic routes [Option 2]:
Whenever you need to return different status codes for server-side rendered pages in Nuxt, you need to use middleware.
This is the main idea - you have to define your own middleware to verify url here (probably with async logic inside).
import { Context } from "@nuxt/types";
import { isUrlValid } from "~/services/validateRoute";
export default async function (context: Context) {
if (!(await isUrlValid(context.route.path))) {
context.error({
statusCode: 404,
message: `Invalid route: ${context.route.path}`,
});
}
}
And to make it work, it should be linked to the corresponding dynamic route page:
import Vue from "vue";
import Component from "vue-class-component";
@Component({
middleware: "validateRoute",
})
export default class RedirectPage extends Vue {}
Working app example is here: https://github.com/DamirsCorner/20210521-nuxt-dynamic-route-404
Source: https://www.damirscorner.com/blog/posts/20210521-404PageForNuxtDynamicNestedRoutes.html
Data fetching errors handling:
Nuxt docs says:
If there is an error when fetching data, the normal Nuxt error page won't be loaded - and you should not use the Nuxt redirect or error methods within fetch(). Instead, you will need to handle it within your component using $fetchState.error.
So, it's pretty straightforward:
<template>
<div>
<p v-if="$fetchState.pending">Loading....</p>
<p v-else-if="$fetchState.error">Error while fetching mountains</p>
<ul v-else>
<li v-for="(mountain, index) in mountains" :key="index">
{{ mountain.title }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
mountains: []
}
},
async fetch() {
this.mountains = await fetch(
'https://api.nuxtjs.dev/mountains'
).then(res => res.json())
}
}
</script>
From this example you can see that you won't be able to change response code, since error in that stage will be interpreted as normal situation with 200 response code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With