Vueのエラー監視にSentryを使ってみた

フロントエンドのエラーって見落としがちですよね。
ユーザーにエラーのアラートを表示しても連絡がなければ開発者はそのエラーに気づくことができません。
そもそもエラー処理が適切に行えておらず、consoleをみるとエラーだらけなんてもことも。

## Sentryでエラーを監視する

[Sentry](https://sentry.io/welcome/)を使えばエラーを見落とすことはなくなるでしょう。発生したエラーをキャッチし、メールやSlackで通知してくれます。

## SDKをインストール

今回はVueで使用するので、Browser > Vueを選択します。

![スクリーンショット 2019-12-04 23.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/2b140f7e-ad45-794f-42ec-9f8a74240b9f.png)

```
yarn add @sentry/browser
yarn add @sentry/integrations
```

``` main.ts
// sentry
import * as Sentry from '@sentry/browser';
import * as Integrations from '@sentry/integrations';
Sentry.init({
  dsn: 'https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  integrations: [new Integrations.Vue({Vue, attachProps: true})],
});
```

## エラー発生するコンポーネントを作成

クリックするとエラーを投げるボタンだけのコンポーネントを作成し、エラーを通知してみましょう。

``` Home.vue
<template>
  <button @click="onError">error</button>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  methods: {
    onError() {
      class ValidationError extends Error {
        constructor(message: string) {
          super(message);
          this.name = "ValidationError";
        }
      }
      throw new ValidationError("ValidationError");
    }
  }
});
</script>
```

## エラー内容

ダッシュボードではエラーのクラス単位で表示されています。

![スクリーンショット 2019-12-05 0.23.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/ba4d453c-ca26-984f-efba-ccde10e4626c.png)![スクリーンショット 2019-12-05 0.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/7d407ca9-d6b1-aca5-aa2c-4d9c00c7b21f.png)


エラーの詳細ページではOS、ブラウザ、IP、イベントを発火した要素、時間、エラーを吐いたソースの行などが記録されています。

![スクリーンショット 2019-12-05 0.29.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/e053f151-79b0-03e9-d9eb-f1f86ce0c483.png)

![スクリーンショット 2019-12-05 0.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/10ce9f7a-f551-673e-22fd-7dc3d8928c9f.png)

## エラー以外の情報を送信したい

Sentry.captureMessageを使うことで、エラー以外のログを残せます。

``` js
captureMessage(message: string, level?: Severity): string;
```

|Sentry.Severity |
|---|
|Sentry.Severity.Critical |
|Sentry.Severity.Info |
|Sentry.Severity.Log |
|Sentry.Severity.Warning |
|Sentry.Severity.Error |
|Sentry.Severity.Fatal |

### APIの通信時間はどれくらいかかってるの？

``` js
const startTimeMilliSec = Math.round(performance.now());
const response = await axios.get('https://yesno.wtf/api');
const endTimeMilliSec = Math.round(performance.now());
const message = `
  loadTimeSec: ${(endTimeMilliSec - startTimeMilliSec) / 1000}
  answer: ${response.data.answer}
`;
Sentry.captureMessage(message, Sentry.Severity.Debug);
```

出力結果は以下の通りです。
API通信のたびに毎回通知が来ても困るので、1秒以上かかった場合などの条件を設けるのがいいかもしれません。

![スクリーンショット 2019-12-07 17.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/ff091a82-e1c2-8358-a447-21db8c87bcc0.png)


## Sentryの管理画面の設定

時間を分かりやすくJST/24時間表示に変更しました。

![スクリーンショット 2019-12-04 23.58.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/9a2ea94a-cfc5-a917-da24-84068dde6a5a.png)

### Slackに通知する

Settings -> Integrations よりSlackを追加します。

Settings -> Alerts -> Rules -> New Alert Rule から通知ルールを設定します。

以上の設定で通知がSlackに来るようになりました。

![スクリーンショット 2019-12-07 18.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/eb9de18b-16d9-5e53-74d0-96c71802f032.png)