2021-1-17

[Sentry] Vue.jsで作成したブラウザ拡張にSentryを入れた際のメモ

技術

ブラウザ拡張のアプリでソースマップを適用する場合の注意

当然だけど、アプリから送られてくるスタックトレースに記載のファイルパスとリリース登録されているファイルパスは揃えられている必要がある。

ただ、ブラウザ拡張の場合スタックトレースに記載されるファイルパスは moz-extension://[id]/js/hoge.js のような形になってしまう。これをなんとか ~/js/hoge.js にする必要がある。

なので自分は以下のようなコードを書いてアプリ側からSentryにデータが送信される前に強制的にデータを書き換えた。

const normalizeUrl = (url: string) => {
  return url.replace(/(moz|chrome)-extension:\/\/[^/]+\//, '~/')
}

Sentry.configureScope(scope => {
  scope.addEventProcessor(async event => {
    if (
      event.exception !== undefined &&
      event.exception.values !== undefined &&
      event.exception.values[0].stacktrace !== undefined &&
      event.exception.values[0].stacktrace.frames !== undefined
    ) {
      event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames.map(
        frame => {
          if (frame.filename !== undefined) {
            frame.filename = normalizeUrl(frame.filename)
          }
          return frame
        }
      )
    }

    return event
  })
})

参考にした情報が configureScope を使用していたので同様にしたが、 beforeSend でやってもよかったかもしれない。

[Suggestion] Javascript source map support for browser extensions

ハンドリングされなかったエラーに対する共通処理がアプリに必要な場合、 @sentry/vue を使えない

Vue.jsアプリの場合、基本的には @sentry/vue を使って Sentry.init すればあらゆるハンドリングされなかったエラーを拾ってSentryに投げてくれるのでそうすればいい。

ただ、今回ハンドリングされなかったエラーをチェックして、特定のAPIからの401エラーが含まれていたら再認証を促すという処理をしたかった。それをやろうとするとSentryデフォルトのエラーハンドリングとバッティングしてしまう。

なので、 @sentry/browser を使用した上で以下のようにGlobalHandlerインテグレーションを無効化した。

Sentry.init({
  ~
  integrations: function(integrations) {
    return integrations.filter(function(integration) {
      return integration.name !== 'GlobalHandlers'
    })
  },
  ~
})

インテグレーションの無効化が結構いかついやりかたに見えるが、Sentryの公式ドキュメントに記載のやり方である。

これをやった上で、必要な箇所で Sentry.captureException(error) をした。

Sentryに送信したくないエラーがある場合、 ignoreErrors オプションを利用する

エラーの中には動作に支障がない、無視したいエラーが存在する。基本的にはSentryの管理画面側でそういうエラーのIgnoreをすればいいんだけど、頻繁に発生するエラーだとSentryの使用枠を無駄に消費してしまう。

そういう場合は、 ignoreErrors に無視したいエラーメッセージを登録しておけばいい。

Sentry.init({
  ~
  ignoreErrors: [
    'Sample ignore error',
  ],
  ~
})

ちなみにこのオプションなんだけど、Sentry公式のBasic Optionsのページに記載がなかった。(TypeScriptの型情報を見て初めて知った)

release名は [project name]@[version] という命名規則で登録する

The sentry-cli tool can be used for release management on Sentry. It allows you to create, edit and delete releases as well as upload release artifacts for them. Note that releases are global per organization. If you want the releases in different projects to be treated as separate entities, make the version name unique across the organization. For example, if you have projectA and projectB that share version numbers, you can name the releases projectA-1.0 and projectB-1.0 respectively.

Release Management

SentryのReleasesだけど、どうもプロジェクト毎に分けられていないみたいで 3.8.1 みたいな名前で登録してると別プロジェクトで同じバージョンが発生した際にバッティングしてしまうみたい。

なので [project name]@[version] というような形で別プロジェクトとバッティングしないようにする必要がある。