JavaScriptのエラーを検知したり、スタックトレースをいいかんじに表示する術
こんにちは。タブの開きすぎで、タブが増やせなくなりました、きたけーです。
JavaScriptのエラー検知
アプリケーション全体のエラーを検知するには、window
オブジェクトにonerror
ハンドラを設定します。こんなかんじ。
window.onerror = function (message, file, line, col, error) { return true; };
ハンドラの引数にエラーメッセージ、発生したファイル名、行数、列数、エラーオブジェクトが渡ります。col と error は、一部のブラウザ(ChromeとかOpera)しか渡らないので注意。
スタックトレースの表示
エラーオブジェクトのスタックはerror.stack
で取得できますが、stacktrace.js
をつかうとスタックトレースをいいかんじで表示できます。
こんなかんじ (stacktrace.js
の導入にはbowerをつかってます)
<script src="./bower_components/stacktrace-js/stacktrace.js"></script> <script> window.onerror = function (message, file, line, col, error) { var trace = printStackTrace({e: error}); alert(trace.join('\n\n')); return true; }; function foo() { unExis(); // ここでエラーになる }; function bar() { foo(); }; bar(); </script>
alertで表示した結果。
stacktrace.js
ですが、そのうち使い方が変わるので注意が必要です。(refs: misnamed function printStackTrace() · Issue #68 · stacktracejs/stacktrace.js · GitHub) issueが閉じられたのが、この記事を書いている1時間前。とほほ。
所感とか疑問
大手Webサービスがクライアント側で発生したJavaScriptのエラーをどう収集しているのか まとめ - Qiita をみると、onerror
でエラーを検知する場合は、(対応しているブラウザがまちまちなので)確実に送信できる内容がエラーメッセージ、行番号、URL(ファイル名)に限定されるのが分かる。
はてなブログの場合だと、アプリケーション全体ではなく、Ajaxの通信であったり、関数の実行のレベルで例外をつかまえているようなので、エラーオブジェクトからスタックトレースを送信できる。
ここで疑問なのがNewRelicのBrowser > JS errors
で、ダッシュボードを見る限り、アプリケーション全体で、かつブラウザを限定せずにスタックトレースが取れているのが分かる。
Announcing JS Error Reporting and AJAX Timing - New Relic blog には、「window.onerrorただつかってるわけじゃないよ」って書いてあったのだけど、どうやって実現しているのかなぁ...
JS stacktraces. The good, the bad, and the ugly. - Bugsnag に書いてあるみたいに機能検出して、関数をラップしたりしているのかな。