こんにちは、”はふぃ”です。

今回は Nuxt.js を使ったエラーページに関する話をしたいと思います。

エラーページとは

エラーページはその名の通り、サイト上でなんらかの不具合(エラー)が発生した時にユーザーにそれを伝えるためのページのことです。

出典:GitHub

上記のようにエラーページには三桁の数字(画像では404)が表示されていることが多いのですが、これは HTTPステータスコード と呼ばれるもので、なんのエラー(エラー以外もありますが)が発生しているのかをコードごとに示すものとなります。

エラーに関する HTTPステータスコード だと 400系500系 があり、400系 がクライアントエラー(ユーザー操作などで発生するエラー)で 500系 がサーバーエラー(システム側でのエラー)を表します。

例えば、上の画像の 404 というエラーは「そんなページは存在しません」というコードなのですが、ページにアクセスするためのURLを入力するのはユーザーで、それが間違っているというエラーなのでクライアントエラーである400系に分類されているというわけです。

以下に代表的な400系と500系のエラーを紹介します。

  • 400系(クライアントエラー)
    • 400(Bad Request):クライアントからサーバーへのリクエストに何らかの不備がある
    • 403(Forbidden):アクセス権がないページにアクセスするなどサービス側で禁止している
    • 404(Not Found):ページが見つからない
  • 500系(サーバーエラー)
    • 500(Internal Server Error):サーバー側で処理方法が分からないエラーが発生した
    • 503(Service Unavailable):サーバーがダウンしていたりメンテナンス中などサービスが利用できない状態
POINT ユーザーの操作によって発生するエラーは400系、システム側で発生しているエラーは500系で表す

エラーページ作成

では、ここから実際にコードや画面で説明しながらエラーページを作っていきます。

Nuxt.js では layouts/error.vue にエラーページのデザインや処理を記入することで全ページ共通のエラーページを作成することができます。

< layouts/error.vue >

<template>
  <div>
    <h1>{{ error.statusCode }}</h1>
    <h1>エラーが発生しました</h1>
  </div>
</template>

<script>
export default {
  props: {
    error: { type: Object, default () { return {} } }
  }
}
</script>

このページでは標準で error というObjectのpropsが渡され、その中に先ほど紹介した HTTPステータスコード を表す statusCode という値を持っています。

statusCode の値はデフォルトでは404なので、例えば /aaa のような存在しないページのURLでアクセスすると以下のような表示になります。

※ わかりやすくするために枠線をひいています

エラーハンドリング(エラーページの表示制御)

エラーページが作成できたので、ここからはエラーハンドリング(発生したエラーに応じて処理を使い分ける)をしながらエラーページをカスタマイズしていこうと思います。

基本的なエラーハンドリング

まずは Nuxt.js の fetch 処理の中でAPIを使ってデータを取得する場面を想定してエラーハンドリングしてみましょう。

API側でエラーが発生した場合はシステムのエラーなので 500系 が使われます。

今回は50%で失敗する(現実ではありえませんが。笑)処理をAPIからデータを取得する処理と仮定して、うまくいった場合には 400 エラーを返す以下のような処理で試してみます。

< pages/sample/errorPage.vue >

<template>
  <div />
</template>

<script>
export default {
  fetch ({ error }) {
    const fetchFn = () => {
      // 50%で失敗する
      if (parseInt(Math.random() * 2, 10) === 1) {
        throw new Error('server error')
      }
      return true
    }

    try {
      // 処理が成功したら400, 失敗したら500
      fetchFn()
      error({ statusCode: 400 })
    } catch (e) {
      error({ statusCode: 500 })
    }
  }
}
</script>

<style></style>
POINT Nuxt.js の fetch (asyncDataも同様) では引数(context)の中に error というメソッドを持っており、これを使うことで statusCode を渡しながらエラーページを表示することができる!
statusCode:400 の場合
statusCode:500 の場合

なお、Nuxt.js の error メソッドを使った場合、エラーページが表示される際にURLが変わらない( /error などにならない)という特徴があるのでサイトによっては注意が必要です!(Google Analyticsなどのツールを使って後からエラー率を取得しようとしている場合など)

バリデーション(validate)を使ったエラー

Nuxt.js では validate という機能を使って、ページにアクセスしてきた時にURLパラメータやURLクエリーが正しいかをチェックすることができます。

先ほどのコードに以下のようなvalidate処理を追加してみましょう。

< pages/sample/errorPage.vue >

…

<script>
export default {
  validate ({ query }) {
    return query.sampleId
  },
  fetch ({ error }) {
  …

今回は sampleId というqueryがついていない場合はバリデーションで弾くような実装にしました。

○:http://localhost:3000/sample/errorPage?sampleId=1

×:http://localhost:3000/sample/errorPage

これで↑の × のパターンのURLでアクセスすると以下のように404エラーの表示になります。

※ validateエラーのstatusCodeは404になります

エラーメッセージを動的に表示

Nuxt.js の error メソッドでは statusCode の他に message というパラメータでエラーメッセージも渡すことができます。

これを使うことでエラーごとに任意のエラーメッセージをエラーページで表示させることが可能です。

< pages/sample/errorPage.vue >

…

try {
  // 処理が成功したら400, 失敗したら500
  fetchFn()
  error({ statusCode: 400, message: '操作にミスがあります。最初からやり直してください。' })
} catch (e) {
  error({ statusCode: 500, message: 'システムがダウンしています。時間をおいてやり直してください。' })
}

…

< layouts/error.vue >

<template>
  <div>
    <h1>{{ error.statusCode }}</h1>
    <h1>{{ error.message }}</h1>
  </div>
</template>

…
statusCode:400 の場合
statusCode:500 の場合

さらに layouts/error.vue でも処理を追加してエラーメッセージを切り替えてみましょう。

< layouts/error.vue >

<template>
  <div>
    <h1>{{ error.statusCode }}</h1>
    <h1>{{ errorMessage }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    error: { type: Object, default () { return {} } }
  },
  computed: {
    errorMessage () {
      if (this.error.statusCode === 404) {
        return 'ページが存在しません'
      }
      if (this.error.message) {
        return this.error.message
      }
      return 'エラーが発生しました'
    }
  }
}
</script>

この状態で先ほどのバリデーションエラーを発生させると、このように設定したエラーメッセージが表示されます。

まとめ

Nuxt.js は layouts/error.vue をいじるだけでエラーページをいじれるので便利ですね!

参考

今回のコードはgithubで公開中なので参考にしてみてください!↓

https://github.com/hafilog/vue-sample/tree/master/components/pages/sample

投稿者: はふぃ

若手のWEBフロントエンジニア。最近はバレーボールにハマってます!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA