FFFT

主にwebプロダクト開発に関連する話をつらつらと

react-reduxアプリケーションにSentryを導入する

react-reduxのアプリケーションにSentryを導入していきましょう。

f:id:keyama4:20180711124419p:plain

サンプルのプロジェクトはcreate-react-appを使用して下記の条件で作っています。

"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-redux": "^5.0.7",
"react-scripts": "1.1.4",
"redux": "^4.0.0"
"redux-saga": "^0.16.0"

ミニマムのサンプルを作ったのでこちらから。
github.com
cloneしてそのまま動作確認もできます。

Sentryにアカウント登録をしてprojectを作成する

アカウント登録後にトップに遷移するのでヘッダの「add new...」を押下して「project」を選択してください。

f:id:keyama4:20180711124929p:plain

次に言語・フレームワークを選択します。
こちらはReactを選択。

f:id:keyama4:20180711125102p:plain

最後にプロジェクト名を入力します。
アプリケーションの単位と合わせて命名するのが良いでしょう。

f:id:keyama4:20180711125223p:plain

入力して「Create Project」を押下すると完了画面が表示されます。

f:id:keyama4:20180711125935p:plain

プロジェクトを作成するとSentry DSNが発行されます。
こちらは公式の下記の記述のとおり設定からいつでも確認できるので画面は閉じちゃって問題なし。

The DSN can be found in Sentry by navigating to [Project Name] -> Project Settings -> Client Keys (DSN).

これにてSentryでの事前準備はオッケーです。

アプリケーションにSentryへの通知を実装する

基本的には公式の下記のとおりに進めていけば問題ないです。

React – Sentry Documentation

index.htmlにraven.jsをロードさせましょう。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>React Redux Sentry</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <script src="https://cdn.ravenjs.com/3.26.2/raven.min.js"
    crossorigin="anonymous"></script>
  </body>
</html>

次にindex.jsにDSNの設定を追加。

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

// TODO: change config arguments to your dsn
window.Raven.config("<YOUR_DSN>").install();
ReactDOM.render(<App />, document.getElementById('root'));

TODOにあるとおり、Sentryの対象のプロジェクトのDSNを設定してください。

reactのバージョン16移行はError Boundariesというcomponentで発生するエラーのハンドリング機構が新しく追加されています。

Error Handling in React 16 - React Blog

こちらのエラー情報をSentryに渡すようにします。

こんな感じでエラーハンドリング用のcomponentを作ります。

react-redux-sentry/error-boundary.jsx at master · keyama4/react-redux-sentry · GitHub

root componentをchildrenにするようにすればオッケーです。
サンプルはindex.jsを修正。

ReactDOM.render(<ErrorBoundary><App /></ErrorBoundary>, document.getElementById('root'));

ここまでの設定でreactで発生するエラーは詳細を含めてすべてSentryで捕捉できるようになりました。
Sentryにはこんな感じでエラーがきます。

f:id:keyama4:20180711144334p:plain

次にreduxの設定です。
今のままでも上述のとおり、reactで発生するエラーは捕捉できるのですがreduxを採用しているアプリケーションであればstoreの状態やエラー発生直前のactionなど知れたら調査がぐっと楽になりますよね。
それをSentryに表示するための設定です。

こちらのmiddlewareを使いましょう。
github.com

後はREADMEにあるようにreduxのapplyMiddleware関数に

createRavenMiddleware(Raven, {
  // Optionally pass some options here.
})

を渡してあげます。

ただ、redux-sagaを使っている場合はtakeEveryで実行されるタスクでエラーが発生するとキャッチされません。
そのため、下記のようにredux-sagaのcreateSagaMiddlewareを書き換えればオッケーです。

const sagaMiddleware = createSagaMiddleware({
  onError(error) {
    setImmediate(() => {
      throw error;
    });
  }
});

サンプルではこちらのファイルになります。

react-redux-sentry/store.js at master · keyama4/react-redux-sentry · GitHub

これで完了です。

reduxのエラーはこんな感じでstateと直前のアクションが見れます。

f:id:keyama4:20180711183709p:plain

Sentryありがとう。

ここまででSentryの設定は完了ですがSlack連携をするとさらに便利に使えます。
下記にまとめたので良ければ見てください。

keyama.hatenablog.com