クライアントのエラーをキャッチする
この記事を読みました。
WEBブラウザで起きた JavaScript のエラーをサーバに送りたい
素晴らしいアイデアですが、AngularJSでは、window.onerror
が発火しないため、通常のやり方が通用しません、とのこと。
そのため、$exceptionHandler
という、例外を集約しているサービスをオーバーライドする必要があります。
以下のように書けば問題ないかと思われます。
angular.module('myApp')
.factory('$exceptionHandler', function($injector) {
return function errorCatcherHandler(exception) {
// オーバーライドしたためブラウザにエラー出力しないので、ここからブラウザにエラー出力する
console.error(exception.stack);
// Circular dependencyを防ぐため、ここで使用サービス(Restangular)をインジェクトする
var Restangular = $injector.get('Restangular');
// 送信するメッセージ
var errorMessage = {
browserType: navigator.userAgent,
error: exception.stack
};
// 送信先を指定
var sendMessage = Restangular.all('where/to/go');
// 送信
sendMessage.post(errorMessage);
};
})
...
コメントにも既に書いてありますが、ポイントとしては2点あります。
1.console.error()を必ずサービス内に入れること
書かないと、ブラウザでエラーが発生しても、ブラウザのコンソールに何も吐かなくなります。
2.$injectorで使用するサービスをインジェクトすること
通常であれば、
.factory('$exceptionHandler', function($injector, Restangular) {...
みたいな書き方で注入すると思いますが、これだと一部のサービスでCircular dependency(循環依存関係)としてエラーになってしまいます。
$exceptionHandler
に$rootScope
を注入しようとしてるんだけど、$rootScope
自体が$exceptionHandler
を注入してて、ぐるぐる回ってなんじゃらほい、ということですね。
そのため、$injector
を使用して、サービスが呼び出された際に、使用するサービスをインジェクトするのがよろしいかと。
サーバーに送ったエラーは、Slackに送るなり、担当者を叱るのに使ったり、ご自由に...