Android: turbo_module.* crash tags permanently pinned to RNSentry.initNativeReactNavigationNewFrameTracking (promise never settles)
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- android, react-native, typescript
- 領域
- mobile
調査の方向性
android/src/main/java/io/sentry/react/RNSentryModuleImpl.java を読み、initNativeReactNavigationNewFrameTracking と ios/RNSentry.mm の iOS 実装を比較してください。src/js/turbomodule/wrapTurboModule.ts で Promise を返すメソッドがどのように処理されているかを確認してください。この issue では、RNSentryModuleImpl 内の他の Promise を受け取るメソッドも監査することが提案されています。この呼び出しによって tracker frame が stuck したままにならず、Android の動作が意図された Promise の settle に一致すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
On Android, the crash-time TurboModule attribution added in #6227 is permanently pinned to a single startup call. Every native crash report from an Android app carries:
turbo_module.name: RNSentry
turbo_module.method: initNativeReactNavigationNewFrameTracking
regardless of what was actually executing. The tags are not stale-by-a-moment; they are stuck for the entire process lifetime, so the feature reports a wrong answer rather than no answer. iOS is unaffected.
Cause
Three facts compose:
-
wrapTurboModulepops a tracker frame for a promise-returning method only when that promise settles (src/js/turbomodule/wrapTurboModule.ts— theisThenable(result)branch pops in boththenhandlers). -
The Android implementation never settles the promise:
// android/src/main/java/io/sentry/react/RNSentryModuleImpl.java public void initNativeReactNavigationNewFrameTracking(Promise promise) { this.initFragmentInitialFrameTracking(); }promiseis accepted and dropped — noresolve, noreject, no path that settles it later. iOS does the equivalent work and then callsresolve(nil)(ios/RNSentry.mm). -
RNSENTRY_SKIPinturboModuleContextIntegrationdoes not include this method, so it is wrapped like any other.
The frame pushed at startup therefore never pops. popTurboModuleCall walks the stack and re-syncs the scope onto "the newest remaining frame on the same scope" after every subsequent pop — which, once the app is idle, is always the leaked startup frame. The native scope is left holding it, and sentry-java serialises it into every crash report.
Two smaller consequences of the same leak: the tracker stack never drains to empty (so clearScope's empty-string sentinel path is unreachable on Android), and the aggregate record for that call is never emitted.
Steps to reproduce
- Expo app on Android with
enableTimeToInitialDisplayon (expoRouterIntegrationorreactNavigationIntegration). - Let the app finish starting, navigate anywhere, idle.
- Trigger any native crash — e.g.
Sentry.nativeCrash()— or readgetTurboModuleCallStack(). - The event's tags report
RNSentry.initNativeReactNavigationNewFrameTrackingas the in-flight call; the stack still holds that frame.
Suggested fix
Settle the promise in the Android implementation, mirroring iOS:
public void initNativeReactNavigationNewFrameTracking(Promise promise) {
this.initFragmentInitialFrameTracking();
promise.resolve(null);
}
Adding the method to RNSENTRY_SKIP would hide the symptom but leave the dangling promise, so the native-side fix seems the right one. It may be worth auditing the other Promise-taking methods in RNSentryModuleImpl for the same shape.
Versions
@sentry/react-native: reproduced on 8.27.0; the Android code is unchanged on 8.29.0 (current latest)- Platform: Android only (iOS resolves correctly)
- 主要言語
- TypeScript
- スター
- 1.8k
- フォーク
- 369
- 平均マージ
- 23時間 27分
- マージ済み PR(30日)
- 112
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
getsentry/sentry-react-native のほかの issue
-
React-Native Replays Task
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
getsentry/sentry-react-native#6680 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Improvement React-Native
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
getsentry/sentry-react-native#6143 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
React-Native Task User Feedbacks
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
getsentry/sentry-react-native#5932 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
React-Native Replays Task
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
getsentry/sentry-react-native#5882 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Good First Issue React-Native Task
難易度 1/5 1時間未満 初心者へのやさしさ 65/100
getsentry/sentry-react-native#5771 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
getsentry/sentry-react-native の issue をすべて見る
似ている issue
-
affected/v17 affected/v18 area/frontend type/bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
umbraco/Umbraco-CMS#24186 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
better-auth/better-auth#11723 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
area: docs difficulty: easy documentation good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
Worker-Erstellung bricht langsame Git-Worktree-Checkouts nach 20 Sekunden ab対応中かも @KajoVanBuyten が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 69/100
AgentSystemLabs/agent-office#367 ·
メンテナーはふだん 1 日以内に返信