そーす

福岡在住のプログラマ。SwiftとかKotlinとかJavascriptとかSketchとか触ってます。

ReactNativeでJavascript側で起きたエラーを取得する

アプリのクラッシュレポートツールを大体入れているかと思うのですが、ReactNativeではどうするのが一般的なんでしょうかね。

FabricのCrashlyticsを入れたのですが、これはネイティブのエラーの箇所をレポートするので自前のネイティブ処理じゃない場合はライブラリ内のエラーの箇所が通知されます。

試しにApp.jsでエラーを投げてみると

f:id:saburesan:20170516161234p:plain

ワケガワカラナイヨ

これだと役に立たないですね…

というわけでJS側で起きるエラーを取得してそれを上手く通知できればいいなぁと思い調べてみました。

調べてみると、ErrorUtilsというオブジェクトがGlobalのプロパティに居るようで、こいつを使うとJS側のエラーをハンドリングできるようです。

github.com

試しにやってみました。一部だけ抜粋してます。

global.ErrorUtils.setGlobalHandler((e, isFatal) => {
  console.log(e);
});

export default class Sample extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Button title="Invoke Error" onPress={() => { throw new Error('test'); }} />
      </View>
    );
  }
}

Chromeのログだとこんな感じ

f:id:saburesan:20170516144300p:plain

log-iosのログだと

line: 64
column: 28,
sourceURL: '/index.ios.bundleplatform=ios&runModule=false&entryModuleOnly=true&hot=true'

取得できてるみたいですね。

リリースビルドだとどうでしょうか。

line: 64,
column: 28,
sourceURL: index.android.bundle

なるほど(?)

index.android.bundleがデフォルトだと無いようなので作ります。

> react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/build/outputs/index.android.bundle

これでAndroidのリリース時のバンドルされたJSファイルが取得出来ます。

f:id:saburesan:20170516155830p:plain

指定の行、列を探してみたらちゃんとthrow Error(‘text’)したコードが見つかりました。

この情報を元にCrashlyticsでレポート送るとかやればいいのかな???

あと調べたら、JavascriptのクラッシュレポートツールにSentryっていうのがあるらしいんですが、これとかって結構使われてるんですかね? AirbnbとかUberとかでの導入実績が在るらしいですが…

sentry.io