エラー監視サービスのSentryをExpoを使用して開発しているReact Nativeアプリに導入し、ある程度動作検証してみます。
画面に沿ってアカウント作成後、
最初はこのようにチュートリアルのような形でプロジェクトを作成できますが、ダッシュボード(トップページ)のProjects→Create Projectからプロジェクト名、プラットフォーム(React-Native)を指定して作成します。
ここからはExpoのドキュメントに従って進めます。
https://docs.expo.io/versions/latest/guides/using-sentry/
必要な情報は
- DSN
プロジェクト作成時に案内が出ているかもしれませんが、Settings→Projects→プロジェクトを選択→Client Keys(DSN)からも取得できます。 - 組織名(Organization)
個人で登録した際は個人名を指定してるかと思います。ケバブケース化されています。 - プロジェクト名
ケバブケース化されています。 - Authトークン
ダッシュボードのSettings→パンくずリストのSettingsで設定のトップへ→API KeysのAuth Tokensページで作成します。
Authトークンの作成時には、Expoのドキュメントに従ってproject:writeをチェックしておきます。

Expoプロジェクト側で設定・初期化する部分は、app.jsonと最初に呼ばれるJSファイルのみです。
まずはsentry-expoをインストールします。publishごとに生成されるIDを取得するため、expo-constantsもインストールしておきます。
$ npm install sentry-expo expo-constants
app.jsonのexpo.hooks.postPublishにこのように設定を追加します。
publish時にSentryにソースマップファイルをアップロードしているようです。
{
"expo": {
"hooks": {
"postPublish": [
{
"file": "sentry-expo/upload-sourcemaps",
"config": {
"organization": "組織名",
"project": "プロジェクト名",
"authToken": "Authトークン"
}
}
]
}
}
}
JS側でSentrySDKをセットアップします。
import * as Sentry from "sentry-expo";
import Constants from 'expo-constants';
Sentry.setRelease(Constants.manifest.revisionId || "DEV");
Sentry.init({
dsn: 'DSNをここに指定',
enableInExpoDevelopment: true,
debug: __DEV__
});
initメソッドにオプションを指定して初期化します。
一応デバッグモードは開発時のみtrueになるようにしておきますが、それほど気にしなくていいみたいです。
先ほどインストールしたexpo-constantsからリビジョンIDをSentryにセットしてあげると、どのバージョンでエラーが発生したかが特定できます。
とりあえずcaptureExceptionメソッドを使って、Expo Clientの開発環境でエラーを発生させてみます。
setUserメソッドでユーザーを特定できるようにしたりできるようなので、これも使ってみます。
Sentry.setUser({"email": "john.doe@example.com"});
Sentry.captureException(new Error('error!'));
The stack is nullとあります。Sentryがうまくスタックトレースにアクセスできてないような感じです(?)。
しかしSentryのissuesを見ると、ちゃんとエラーイベントが取得できているようです。ユーザーも問題なくセットできています。

今度は明示的にcaptureExceptionを使うのではなくエラーを発生させてみます。
Sentry.setUser({"email": "john.doe@example.com"});
global.foo(); // 存在しないfunction
こちらは当然Expo Clientの画面では通常のエラー表示になります。
Sentryの方でも問題なくエラーが取得できていました。
ちなみに、先ほどsetReleaseにDEVが入るようにしているので、RELEASE欄にはちゃんとDEVと表示されています。
では、リリース後のアプリでも確認してみます。
以前作ったQRコード生成のアプリにこっそりとエラーを発生させる仕組みを仕込んで、Expoでpublishしてみます。
<TouchableWithoutFeedback
onPress={() => {
throw new Error('error test!');
}}
>
<View
style={{
position: "absolute",
top: 0,
left: 0,
width: 70,
height: 70
}}
/>
</TouchableWithoutFeedback>
タップするとエラーを発生させる隠しボタンを追加してpublishでOTAアップデートし、
アプリを起動してエラーを発生してみます。
Sentryの方でも問題なくエラーが取得できています。
setReleaseで設定しているので、RELEASE欄にはExpoが自動で生成しているユニークな値が入っています。
エラーの詳細を見ると、元ソースもエラーが発生した位置もちゃんと閲覧できます。
ユーザーのいないしょぼいアプリとはいえ、そのままにしていたら普通にまずいのですぐ消しました。
今回試してみたのはRELEASEやUSERのみですが、他にも色々とコンテキストを設定できるようです。
詳しくはドキュメントを参照してください。
ただし、一部React Nativeでは対応していないものがあるようです。例えばコンソールの内容を送信するためのSentry.Integrations.CaptureConsoleなどは使用できませんでした。



