AngularJSで、ブラウザのJavascriptエラーをサーバーに送る


クライアントのエラーをキャッチする

この記事を読みました。

WEBブラウザで起きた JavaScript のエラーをサーバに送りたい

素晴らしいアイデアですが、AngularJSでは、window.onerrorが発火しないため、通常のやり方が通用しません、とのこと。
そのため、$exceptionHandlerという、例外を集約しているサービスをオーバーライドする必要があります。

以下のように書けば問題ないかと思われます。

app.js

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に送るなり、担当者を叱るのに使ったり、ご自由に...