エラーの処理、どうしていますか?
今まで毎回下のようにコードに埋め込んでいたのですが、これではエラーハンドリングやエラーメッセージの保守コストが高くなります。
throw new Error('エラーだよ。')
よりDRYに書く方法はないかと調べているとすばらしい記事がヒットしました。
https://speakerdeck.com/nori3tsu/vue-dot-js-nuxt-dot-jsfalsekuroharuerahantorinkushi-zhuang
vueのpluginとしてエラーハンドリングを登録することでグローバルレベルでエラーハンドリングの定義が可能です。
また、自作のエラークラス(CustomError)を作成することでエラーの可読性や再利用性を高めています。
以下でvue3での実装を忘備録として書き残します。
エラープラグインを作成・登録
ErrorHandlingPlugin.ts
import { App } from 'vue'
import { CustomError, MissingConnectionError } from 'CustomError'
const ErrorHandlingPlugin = {
install: function (app: App<Element>) {
app.config.errorHandler = (err: unknown) => {
handler(err)
}
// Vue.js以外のエラー
window.addEventListener('error', (event) => {
handler(event.error)
})
// Promise経由で呼び出されるエラー(Promise.reject)
window.addEventListener('unhandledrejection', (event) => {
handler(event.reason)
})
},
}
const handler = (err: unknown) => {
if (err instanceof MissingConnectionError) {
alert(err.message)
// retry、画面再読み込みなど
} else if (err instanceof 自作のエラークラス) {
// ...
} else if (err instanceof CustomError) {
console.info('CustomError')
// エラー後の共通の処理(モーダル出すとか)
} else if (err instanceof Error) {
console.error('Error')
// エラー後の共通の処理(5xxエラー画面飛ばすとか)
}
}
export { ErrorHandlingPlugin }
main.ts
import { createApp } from 'vue'
import { ErrorHandlingPlugin } from 'ErrorHandlingPlugin'
const app = createApp(App)
app.use(ErrorHandlingPlugin)
// ...
自作のエラークラス
CustomError.ts
// メッセージの内容はenumで定義しておく
const ErrorMessage = {
MISSING_CONNECTION: '通信エラーが発生しました。',
} as const
type ErrorMessage = typeof ErrorMessage[keyof typeof ErrorMessage]
interface CustomErrorInterface {
message: string
name: string
}
class CustomError extends Error implements CustomErrorInterface {
constructor(message: string) {
super(message)
this.name = 'CustomError'
}
}
// 自作のエラーはCustomErrorを拡張。命名としてErrorをつけるようにしている
class MissingConnectionError extends CustomError {
constructor() {
super(ErrorMessage.MISSING_CONNECTION)
this.name = 'MissingConnectionError'
}
}
export {
ErrorMessage,
CustomError,
MissingConnectionError,
}
エラー呼び出し
あとはエラーが出た時に自作エラーを投げれば共通の処理を行なってくれます!
client.js
try {
// エラーが出そうな処理
} catch (e) {
console.error(e)
throw new MissingConnectionError()
}