Skip to content

fix(android): Recover missing JS stack traces from native JavascriptException#5964

Closed
antonis wants to merge 4 commits intomainfrom
antonis/fix-missing-stacktrace-android
Closed

fix(android): Recover missing JS stack traces from native JavascriptException#5964
antonis wants to merge 4 commits intomainfrom
antonis/fix-missing-stacktrace-android

Conversation

@antonis
Copy link
Copy Markdown
Contributor

@antonis antonis commented Apr 7, 2026

📢 Type of change

  • Bugfix

📜 Description

On Android with Hermes, React render errors can arrive at the JS-side ErrorUtils.setGlobalHandler without a .stack property. The same error is captured by React Native's native layer as a JavascriptException which contains the full JS stack trace string (with component names and bundle offsets).

Previously, JavascriptException was fully ignored via addIgnoredExceptionForType, discarding the stack information entirely. This PR:

  1. Intercepts JavascriptException in beforeSend instead of ignoring it — caches the stack trace string, then drops the event (same dedup behavior)
  2. Exposes the cached stack to JS via a sync bridge method (fetchCachedJavascriptExceptionStack)
  3. Recovers the stack in a new NativeStackRecovery integration that fetches and parses the cached stack when an event has no frames

The cache uses AtomicReference with a 5-second TTL and single-consumption (getAndClear) semantics.

💡 Motivation and Context

Fixes #5071

A user reported a fatal error "Value is undefined, expected an Object" arriving in Sentry with zero stacktrace frames, while Crashlytics captured the same error with a full stack as a JavascriptException. The root cause is that React's error handling transforms render errors before they reach the JS global error handler, stripping the .stack property. The native JavascriptException retains the original stack but was being discarded.

See also: https://x.com/TheAnirudh/status/1954761591515476463

💚 How did you test it?

  • 9 new JS tests for NativeStackRecovery integration (all branches covered)
  • 3 new/updated Android unit tests for beforeSend JavascriptException handling
  • Integration ordering test verifying NativeStackRecovery runs before RewriteFrames
  • Verified defaultStackParser correctly parses JavascriptException.getMessage() format including address at prefixes
  • All 1219 tests pass, 0 lint errors, no circular dependencies

📝 Checklist

  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing
  • No breaking changes

🔮 Next steps

  • Verify with a real Android/Hermes app that the recovered stack frames are correctly symbolicated by Sentry's server
  • Consider if a similar issue exists on iOS (currently iOS does not exhibit this problem)

…xception

On Android with Hermes, React render errors can arrive at the JS-side
ErrorUtils.setGlobalHandler without a .stack property. The same error
is captured by RN's native layer as a JavascriptException which contains
the full JS stack trace string.

Previously, JavascriptException was fully ignored via
addIgnoredExceptionForType, discarding the stack information. Now we
intercept it in beforeSend, cache the stack trace, and expose it to JS
via a sync bridge method. A new NativeStackRecovery integration fetches
and parses the cached stack when an event has no frames.

Fixes #5071

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix(android): Recover missing JS stack traces from native JavascriptException by antonis in #5964
  • fix(ios): Add SENTRY_PROJECT_ROOT env var for monorepo support by antonis in #5961
  • feat(ios): Add attachAllThreads option by antonis in #5960
  • fix(core): Lazy-load Metro internal modules to prevent Expo 55 import errors by lucas-zimerman in #5958
  • chore(deps): update Cocoa SDK to v9.9.0 by github-actions in #5956
  • chore(deps): update Maestro to v2.4.0 by github-actions in #5955
  • Feat: Fallback to stacktrace parsing by lucas-zimerman in #5946
  • fix(ci): Bump Node to 22 in size-analysis and testflight workflows by antonis in #5954
  • feat(playground): Open Sentry in desktop browser from Expo apps by antonis in #5947
  • chore(core): Bump sample app to React Native 0.84.1 by antonis in #5941
  • Size analysis for React Native SDK by alwx in #5949
  • chore(deps): bump lodash from 4.17.23 to 4.18.1 by dependabot in #5953
  • chore(deps): bump yauzl to ^3.2.1 by antonis in #5950
  • chore(deps): bump brace-expansion to ^2.0.3 by antonis in #5951
  • chore(deps): bump @xmldom/xmldom to fix XML injection by antonis in #5952

🤖 This preview updates automatically when you update the PR.

@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Apr 7, 2026

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit efac955. Configure here.

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Apr 7, 2026
@sentry
Copy link
Copy Markdown

sentry bot commented Apr 7, 2026

Sentry Build Distribution

App Name App ID Version Configuration Install Page
Sentry RN io.sentry.reactnative.sample 8.7.0 (82) Release Install Build

@antonis
Copy link
Copy Markdown
Contributor Author

antonis commented Apr 7, 2026

Superseded by a simpler approach — using React's componentStack as a fallback instead of bridging the native JavascriptException stack. See new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing stacktrace in Value is undefined, expected an Object Error

1 participant