こんにちは、”はふぃ”です。
今回は Nuxt.js を使ったエラーページに関する話をしたいと思います。
目次
エラーページとは
エラーページはその名の通り、サイト上でなんらかの不具合(エラー)が発生した時にユーザーにそれを伝えるためのページのことです。

上記のようにエラーページには三桁の数字(画像では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):サーバーがダウンしていたりメンテナンス中などサービスが利用できない状態
エラーページ作成
では、ここから実際にコードや画面で説明しながらエラーページを作っていきます。
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>


なお、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>
…


さらに 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