LoginSignup
34
28

More than 3 years have passed since last update.

Nuxt.js で axios を利用しての NuxtServerError エラー対応備忘録

Posted at

Nuxt.js のSSR(ユニバーサル SSR)ではまったポイントの備忘録

自分が困ったので、また次に困った人が無駄な時間を使わないことを祈りながらの備忘録

実行環境

  • "node": "v11.10.0"
  • "npm": "6.9.0"
  • "nuxt": "2.9.2"
  • "@nuxtjs/axios": "5.6.0"

NuxtServerError Request failed with status code xxx

asyncDataできちんとtry&catchの実装を行なっているか確認すること

  // 良い例
  async asyncData({ app, error }) {
    try {
      const response = await app.$axios.$get('https://httpbin.org/status/403')
      return { hoge: response.headers.Host };
    } catch (err) {
      error({
        statusCode: err.response.status,
        message: err.response.data.message,
      });
    }
  },
  // 悪い例
  async asyncData({ app }) {
    const response = await app.$axios.$get('https://httpbin.org/status/403')
    return { hoge: response.headers.Host };
  },

RangeError Maximum call stack size exceeded

catchではerrorで返してあげること

  // 良い例
  async asyncData({ app, error }) {
    try {
      const { headers } = await app.$axios.$get('https://httpbin.org/get');
      return { hoge: headers };
    } catch (err) {
      error({
        statusCode: err.response.status,
        message: err.response.data.message,
      });
    }
  },
  // 悪い例
  async asyncData({ app }) {
    try {
      const response = await app.$axios.$get('https://httpbin.org/status/403')
      return { hoge: response.headers.Host };
    } catch (err) {
      return err.response;
    }
  },

エラーページ(layouts/error.vue)のカスタマイズ

エラーページは ページコンポーネント で、エラーが発生したときに常に表示されます(サーバーサイドレンダリング中には発生しません)。

きちんとtry&catchの実装を行なっているとエラーページも必要になってくるので追記。

デフォルトのエラーページのソースコードは、GitHubから入手できます。

公式サイトでは、[GitHubから入手できます。] と書いてあったので、そのまま使えるのかと思いましたが、

<% if(debug) { %>
  <p class="description" v-else><%= messages.client_error_details %></p>
<% } %>

上記のような記述があったため、デフォルトのエラーページだと動かなかったので、そのコンポーネントを参考に作成してみました。

ディレクトリ構成

サンプルでしたので簡略化

layouts/
--| error.vue
components/
--| nuxt-error.vue

layouts/error.vue

<template>
 <div class="container">
    <nuxt-error :error='error'></nuxt-error>
  </div>
</template>

<script>
import NuxtError from '@/components/nuxt-error'

export default {
  props: ['error'],
  components: {
    NuxtError,
  },
}
</script>

components/nuxt-error.vue

<template>
  <div class="__nuxt-error-page">
    <div class="error">
      <div class="title">{{ message }}</div>
      <NuxtLink class="error-link" :to="link.to">{{ link.name }}</NuxtLink>
    </div>
  </div>
</template>

<script>
export default {
  name: 'NuxtError',
  props: {
    error: {
      type: Object,
      default: null
    }
  },
  head () {
    return {
      title: this.message,
      meta: [
        {
          name: 'viewport',
          content: 'width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'
        }
      ]
    }
  },
  computed: {
    statusCode () {
      return (this.error && this.error.statusCode) || 500;
    },
    message () {
      if (this.error.statusCode === 404) {
        return 'このページは存在しません。';
      }
      return this.error.message || `エラーが発生しました。`;
    },
    link () {
      switch (this.error.statusCode) {
        case 403:
          return { to: '/login', name: 'ログイン画面へ戻る' };
          break;
        case 404:
          return { to: '/', name: 'トップへ戻る' };
          break;
        default:
          return { to: '/', name: 'トップへ戻る' };
      }
    },
  }
}
</script>

<style>
.__nuxt-error-page {
  padding: 1rem;
  background: #F7F8FB;
  color: #47494E;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  font-family: sans-serif;
  font-weight: 100 !important;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.__nuxt-error-page .error {
  max-width: 100%;
}
.__nuxt-error-page .title {
  font-size: 1.5rem;
  margin-top: 15px;
  color: #47494E;
  margin-bottom: 8px;
}
.__nuxt-error-page .description {
  color: #7F828B;
  line-height: 21px;
  margin-bottom: 10px;
}
.__nuxt-error-page a {
  color: #7F828B !important;
  text-decoration: none;
}
.__nuxt-error-page .logo {
  position: fixed;
  left: 12px;
  bottom: 12px;
}
</style>

間違っていたら、ご指摘ください。よろしくお願いいたします。

Nuxt.js のライフサイクルをしっかり見ていれば、すんなり解決できたんだろうなと思う今日この頃。

毎度のことながら、
公式サイトはしっかり見ましょうYOという教訓を得られました。

参考文献

Axios Module
NuxtJS はじめに
Vue.js v2 スタイルガイド

34
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
28