🔗 グローバルなエラーハンドラ
こんなときに使いたい
Stimulusに関連するエラー(connect
エラー、targets
にアクセスできないなど)やアプリケーションエラーをコントローラ内でキャッチして、SentryやHoneybadgerなどのエラートラッキングサービスに送信したい場合。
ソリューション
最初に、自分のStimulusコントローラが継承するグローバルなApplicationController
を作成します。
このApplicationController
の中でhandleError
関数を定義します。この関数は、現在のユーザーidで小さなコンテキストオブジェクトを作成します。このコンテキストオブジェクトには、環境やサブスクリプションステータスなどデバッグに役立つあらゆるコンテキスト情報を渡せます。
Stimulusには、ドキュメントにほとんど書かれていないエラーハンドラが含まれています(末尾のリンクを参照)。デフォルトでは、このエラーハンドラはすべてのStimulus内部エラーをキャッチし、整形してからconsole.log
に出力します。
定義したhandleError
関数内でこのapplication.handleError
にカスタムコンテキストを渡して呼び出すことで、エラーの管理や報告を行う単一の関数を利用できるようになります。
Good
// app/javascript/controllers/application_controller.js
import { Controller } from "stimulus";
export default class extends ApplicationController {
handleError = (error) => {
const context = {
controller: this.identifier,
user_id: this.userId,
};
this.application.handleError(
error,
`Error in controller: ${this.identifier}`,
context
);
};
get userId() {
return this.metaValue("user_id");
}
}
これで、以下のように自分のコントローラでエラーをキャッチし、 this.handleError
に渡してエラーを報告できるようになります。
// app/javascript/controllers/some_controller.js
export default class extends ApplicationController {
someFunc() {
try {
// ...
} catch (err) {
this.handleError(err);
}
}
}
通知サービスを追加する
以下はStimulusのエラーをSentryに送信する設定例です。
Good
// app/javascript/packs/application.js
import { Application } from "stimulus";
import { definitionsFromContext } from "stimulus/webpack-helpers";
const application = Application.start();
const context = require.context("./controllers", true, /\.js$/);
application.load(definitionsFromContext(context));
// デフォルトのハンドラをメモ化
const defaultErrorHandler = application.handleError.bind(application);
// Sentryをエラーログに設定してデフォルトハンドラをprependする
const sentryErrorHandler = (error, message, detail = {}) => {
defaultErrorHandler(error, message, detail);
Sentry.captureException(error, { message, ...detail });
};
// 新たに組み立てたハンドラでデフォルトハンドラをオーバーライド
application.handleError = sentryErrorHandler;
これで、このハンドラはグローバルなエラーをSentryに送信します。さらに上の例では、アプリケーションコード内のtry
/catch
ブロックでこの関数を使ってエラーをキャッチする方法も示されています。
そうする理由
すべての理論的根拠は、単一のエラーハンドラでStimulusコントローラ内のすべてのエラーをハンドリングできるようにするためです。Stimulusのエラーもアプリケーションのエラーも、すべて同じパスを通ります。このエラーハンドラを設置するだけで、エラーメッセージにコンテキストを追加して、SentryやHoneybadgerなどに手軽に送信できます。
参考情報
- Github issue discussing the internals of calling application code from Stimulus
- Github PR introducing the error handler
概要
原著者の許諾を得て翻訳・公開いたします。