Android: turbo_module.* crash tags permanently pinned to RNSentry.initNativeReactNavigationNewFrameTracking (promise never settles)

Fermée Adaptée aux débutants
#6,821 2 commentaires 0 réactions 1 personne assignée Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@antonis y travaille déjà.

Depuis le 2/10/2026.

  • #6823 par @antonis — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
78/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
android, react-native, typescript
Domaine
mobile

Piste de recherche

Lisez android/src/main/java/io/sentry/react/RNSentryModuleImpl.java et comparez initNativeReactNavigationNewFrameTracking avec l’implémentation iOS dans ios/RNSentry.mm. Vérifiez comment les méthodes qui renvoient des Promises sont gérées dans src/js/turbomodule/wrapTurboModule.ts ; l’issue suggère également d’auditer les autres méthodes qui prennent des Promises dans RNSentryModuleImpl. C’est terminé lorsque cet appel ne laisse plus un frame du tracker bloqué et que le comportement Android correspond au règlement attendu de la Promise.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Bug React-Native
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:

  1. wrapTurboModule pops a tracker frame for a promise-returning method only when that promise settles (src/js/turbomodule/wrapTurboModule.ts — the isThenable(result) branch pops in both then handlers).

  2. The Android implementation never settles the promise:

    // android/src/main/java/io/sentry/react/RNSentryModuleImpl.java
    public void initNativeReactNavigationNewFrameTracking(Promise promise) {
      this.initFragmentInitialFrameTracking();
    }
    

    promise is accepted and dropped — no resolve, no reject, no path that settles it later. iOS does the equivalent work and then calls resolve(nil) (ios/RNSentry.mm).

  3. RNSENTRY_SKIP in turboModuleContextIntegration does 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
  1. Expo app on Android with enableTimeToInitialDisplay on (expoRouterIntegration or reactNavigationIntegration).
  2. Let the app finish starting, navigate anywhere, idle.
  3. Trigger any native crash — e.g. Sentry.nativeCrash() — or read getTurboModuleCallStack().
  4. The event's tags report RNSentry.initNativeReactNavigationNewFrameTracking as 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)
Langage dominant
TypeScript
Étoiles
1.8k
Forks
373
Merge moyen
1 j 7 h
PR mergées (30 j)
106

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de getsentry/sentry-react-native

Toutes les issues de getsentry/sentry-react-native

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.