個人のWebサービスのエラー通知にRollbarを利用しているのですが、以下の通りデフォルトではVueアプリケーション内で発生したエラー(コンポーネント内のロジックでエラーが起きたケース等)は通知されないことに今更気づき、通知されるようにしたので対応したことをメモ📝
Add Rollbar to Vue’s global error handler. Uncaught exceptions within the Vue app are sent to this handler, and appear in the browser console, but are not sent > to the browser’s global error handler. Adding Rollbar here ensures that these errors are reported. https://docs.rollbar.com/docs/vue-js
Rollbarへ通知するためのプラグインを追加
ほぼドキュメントの通りですが、app.config.errorHandler
を設定し、Vueアプリケーションでエラーが発生した場合にRollbarへの通知ロジックが実行されるようなPluginを用意して、
// NOTE: Rollbarにブラウザ側で発生したエラー通知を送る機能を有効化 // https://docs.rollbar.com/docs/browser-js import Rollbar from "rollbar"; import type { App } from "vue"; const token = process.env.ROLLBAR_POST_CLIENT_ITEM_ACCESS_TOKEN; const rollbarParamsValidation = () => !!(!(NODE_ENV === "test") && token); const rollbar = new Rollbar({ accessToken: token, captureUncaught: true, captureUnhandledRejections: true, enabled: rollbarParamsValidation(), payload: { environment: NODE_ENV, }, }); export default rollbar; // NOTE: Vueアプリケーション内部のエラーをRollbarに通知するプラグイン // https://docs.rollbar.com/docs/vue-js export const VueRollbarPlugin = { install(app: App) { app.config.errorHandler = (error, _vm, info) => { // NOTE: 公式docでは以下となっていたが、おそらく送信時にvueComponentをjsonに変換するのにブラウザがフリーズするため送信しないようにした。 // rollbar.error(error, { vueComponent: vm, info }); rollbar.error(error as Error, { info }); // NOTE: 本来はエラーをコンソールに出力するのは避けるべきだが、 // エラー発生時にconsole.errorに表示しておいた方が確認しやすいため残している // eslint-disable-next-line no-console console.error(error); }; app.provide("rollbar", rollbar); }, };
Pluginの有効化
以下のようにcreateApp時にuseして有効化するようにしました。
import NavigationBar from "@js/components/organisms/NavigationBar.vue"; import { VueRollbarPlugin } from "@js/services/Rollbar"; import { createApp } from "vue"; const app = createAppWithDefault({ components: { NavigationBar } }); app.use(VueRollbarPlugin); app.mount("#vue-header");
また、毎回これを書くのはめんどくさそうに思ったのでcreateAppWithDefault
を定義して、
import { createApp, type CreateAppFunction } from "vue"; import { VueRollbarPlugin } from "./Rollbar"; type VueCreateAppType = CreateAppFunction<Element>; export const createAppWithDefault: VueCreateAppType = (...args: Parameters<VueCreateAppType>) => { const app = createApp(...args); app.use(VueRollbarPlugin); return app; };
以下のように利用するとcreateApp
後に自動的にuse
するようにしました。
import NavigationBar from "@js/components/organisms/NavigationBar.vue"; import { createAppWithDefault } from "@js/services/Vue"; const app = createAppWithDefault({ components: { NavigationBar } }); app.mount("#vue-header");
おまけ:Sentryのケース
Sentryの場合には、@sentry/vue
が提供されていてDocumentの通りに設定すると自動的にapp.config.errorHandler
をよしなに設定してくれるっぽかった。