Sentry は、プロダクションアプリのエラーを追跡できる人気のエラー追跡サービスです。 Sentryは有料サービスですが、寛大な無料プランがあり、アプリではオープンソースのRaven-jsクライアントを使用してSentryとのインターフェースを取ります。 Sentry forAngular2+アプリの起動と実行について見ていきましょう。

インストール

始めるのはとても簡単です。 Yarnまたはnpmを使用してRaven-jsクライアントをインストールするだけです。

$ npm install raven-js --save

# or with Yarn:
$ yarn add raven-js

次に、アプリモジュールでクライアントを設定します。

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ErrorHandler } from '@angular/core';
import { AppComponent } from './app.component';

import * as Raven from 'raven-js';
Raven
  .config('https://<YOUR-SENTRY-KEY>@sentry.io/<YOUR-PROJECT-ID>')
  .install();
export class RavenErrorHandler implements ErrorHandler {
  handleError(err: any): void {
    Raven.captureException(err.originalError);
  }
}

ヒント:本番環境でのみエラーを追跡する

Sentryが本番アプリでのみエラーを追跡し、開発モードのときにエラーをコンソールに記録したままにする必要があります。

次のようなものを使用して、本番環境でのみRavenErrorHandlerクラスをエラーハンドラーとして提供できます。 ここで環境変数が使用されていることに注意してください。

app.module.ts
// ...

import { environment } from '../environments/environment';
import * as Raven from 'raven-js';

Raven
  .config('https://<YOUR-SENTRY-KEY>@sentry.io/<YOUR-PROJECT-ID>')
  .install();

export class RavenErrorHandler implements ErrorHandler {
  handleError(err: any): void {
    Raven.captureException(err.originalError);
  }
}

export function provideErrorHandler() {
  if (environment.production) {
    return new RavenErrorHandler();
  } else {
    return new ErrorHandler();
  }
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [{ provide: ErrorHandler, useFactory: provideErrorHandler }],
  bootstrap: [AppComponent]
})
export class AppModule {}

そしてそれはそれです😅。 これで、本番環境で未処理のエラーがスタックトレースとともにSentryダッシュボードに報告されます。 問題の報告をアプリのユーザーに頼るよりもはるかに優れています。

その他の使用例

エラーは自動的に追跡されますが、ユーザーコンテキストを提供し、Sentryに追加のブレッドクラムを提供することで、もう少し先に進むことができます。

setUserContext

setUserContext を使用して、Sentryのユーザーコンテキストを設定できます。 これにより、どのユーザーがエラーを引き起こしたかを簡単に知ることができます。

// ...

import * as Raven from 'raven-js';

@Component({ ... })
export class AppComponent implements OnInit {
  ngOnInit() {
    Raven.setUserContext({
      username: 'Good Ol Paul',
      email: '[email protected]',
      id: '777'
    });
  }
}

これにより、エラーは問題のユーザーに関連付けられます。 ユーザーがログアウトすると、引数なしで setUserContext を呼び出すことで、コンテキストをリセットできます。

Raven.setUserContext()

実際のアプリでは、ある種の認証サービスからユーザーコンテキストを設定および設定解除することをお勧めします。

CaptureBreadcrumb

セントリーのブレッドクラムは、エラーにつながる一連のイベントです。 Sentryは、可能な場合にこれらのブレッドクラムを自動的に作成しますが、必要に応じて明示的に提供することもできます。

// ...

import * as Raven from 'raven-js';

@Component({ ... })
export class AppComponent implements OnInit {
  ngOnInit() {
    Raven.captureBreadcrumb({
      category: 'Authorization',
      level: 'info',
      message: 'User tried to access restricted area',
      type: 'navigation'
    });
  }
}

CaptureException

captionException を使用すると、エラーをキャプチャするようにSentryに手動で指示できます。 Sentryをアプリのグローバルエラーハンドラーとして使用せず、代わりに手動の例外キャプチャをトリガーする場合は、これを使用します。

onChange(event) {
  try {
    event.target.value.map(x => {
      console.log(x * 2);
    });
  } catch (e) {
    Raven.captureException(new Error(`Oops, something went wrong: ${e}`));
  }
}

以上で、 event.target.value は文字列であり、 map 関数は文字列に存在しないため、Sentryは次のエラーをキャプチャします。

Oops, something went wrong: TypeError: event.target.value.map is not a function