19
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-17

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

この記事を読みました。

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

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?