Skip to content

fix(android): Don't swallow interrupts while flushing a startup crash - #6568

Open
runningcode wants to merge 2 commits into
mainfrom
no/restore-interrupt-send-cached-envelope
Open

runningcode wants to merge 2 commits into
mainfrom
no/restore-interrupt-send-cached-envelope

Conversation

@runningcode

@runningcode runningcode commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

📜 Description

One of the issues with broad catches is that you can ignore the interrupt.
This changes the code so that the calling thread's interrupt isn't ignored.

Concrete summary of the impact from my clanker:
After a crash during the previous app start, register blocks the thread that calls
Sentry.init for up to startupCrashFlushTimeoutMillis (5 seconds by default) while the cached
envelopes are sent. If that thread was interrupted:

  • future.get() threw InterruptedException, which cleared the thread's interrupt.
  • The trailing catch (Throwable) swallowed it, so the code that owns the thread never saw the
    interrupt.
  • It logged "Cached events will not be sent", although the task was already submitted and keeps
    sending them.

InterruptedException is now caught next to the existing TimeoutException. It restores the
interrupt and logs that the send continues in the background.

💡 Motivation and Context

Found during the catch (Throwable) audit (#6564, against 9.x.x).

It rarely shows up on the Android main thread, which nothing interrupts. It matters when an app
initializes Sentry on a worker thread that gets cancelled, for example by
ExecutorService.shutdownNow(), during that wait.

  • Related to JAVA-552

💚 How did you test it?

Added a unit test that interrupts the calling thread before register, while the startup crash
flush is still running. It checks that the interrupt survives and that the cached envelopes are
still sent in the background. The test fails without the fix.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the 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.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

🤖 Generated with Claude Code

After a startup crash, SendCachedEnvelopeIntegration blocks the thread that calls Sentry.init
until the cached envelopes are sent. If that thread was interrupted, future.get() cleared the
interrupt and the trailing catch (Throwable) swallowed it, so the caller never saw it. It also
logged that cached events will not be sent, although the task keeps sending them.

Catch InterruptedException next to the timeout, restore the interrupt and continue in the
background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Nov 11, 2026

Copy link
Copy Markdown

JAVA-552

@sentry

sentry Bot commented Nov 11, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.63.0 (1) release

⚙️ sentry-android Build Distribution Settings

@runningcode
runningcode marked this pull request as ready for review November 11, 2026 15:58
@runningcode
runningcode requested review from a team and adinauer as code owners November 11, 2026 15:58
@runningcode
runningcode requested review from 0xadam-brown and markushi and removed request for a team November 11, 2026 15:58

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant