Skip to content

chore(util): Add CompileOnlyCompat for compile-only linkage errors#5565

Open
0xadam-brown wants to merge 1 commit into
mainfrom
chore/compile-only-utilities
Open

chore(util): Add CompileOnlyCompat for compile-only linkage errors#5565
0xadam-brown wants to merge 1 commit into
mainfrom
chore/compile-only-utilities

Conversation

@0xadam-brown

Copy link
Copy Markdown
Member

I'm not convinced this PR is worthwhile: see the "Callouts" section below.

📜 Description

Introduces an internal helper for calling compileOnly APIs that may be missing or binary-incompatible at runtime.

Adopted in SentrySQLiteDriver and SentryLayoutNodeHelper to replace ad-hoc try/catch blocks.

💡 Motivation and Context

We frequently use compileOnly dependencies to instrument code so that users can remain free to chose their preferred version. That means the shape of the dependency we compile against may not match what shows up at runtime. In particular, if the dependency has an API that adds methods over time, users can crash if we don't use try-catch blocks when calling those methods. The utilities introduced here help us raise awareness about the issue and centralize our approach.

⚠️ Callouts

Not in love with this PR (my vote would be to close it and wait for more examples to show up, if ever), but I'm posting b/c I said I would in our sync + I wanted folks to have a chance to weigh in. IMO, it's heavyweight for what ended up being just two call sites. And there's probably no way to keep everyone happy with the approach.

A number of reasons for that:

[1] If we want these utilities to be generally available, they need to live in the core sentry module. That module is Java-only, and that means making Kotlin call sites look reasonably idiomatic can be tricky.

[2] We can't easily make them Kotlin-only as there's no "core"/"util" Kotlin module that all other Kotlin modules depend on. (The closest is sentry-kotlin-extension, but those are externally-facing and higher-level than the abstractions here.)

[3] Extracting try-catch logic into a method requires using lambdas / SAMs, and that means an additional object allocation relative to an inline try-catch. (We can't use an inline function b/c of [1]/[2].)

[4] Sometimes fallbacks are themselves lambdas rather than a simple default value. That means two lambda args, which further complicates call sites. (Eg, my first approach was T withFallbackIfAbsent(T fallback, Callable<T> callable), but the additional Callable for the fallback case made that less-than-lovely. Plus, putting the fallback first was misleading in the case of booleans, as it looks like you're opting out of some under-the-hood functionality: withFallbackIfAbsent(false) { delegate.doSomething() }.)

Sigh.

💚 How did you test it?

New unit tests + existing tests still pass.

📝 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.

🔮 Next steps

…backs

Introduces a small internal helper for calling compileOnly APIs that may be missing or binary-incompatible at runtime.

Adopt it in SentrySQLiteDriver and SentryLayoutNodeHelper to replace ad-hoc try/catch blocks.
@0xadam-brown 0xadam-brown changed the title chore(util): Add CompileOnlyCompat for compile-only LinkageError fallbacks chore(util): Add CompileOnlyCompat for compile-only LinkageErrors Jun 18, 2026
@0xadam-brown 0xadam-brown changed the title chore(util): Add CompileOnlyCompat for compile-only LinkageErrors chore(util): Add CompileOnlyCompat for compile-only linkage errors Jun 18, 2026
@sentry

sentry Bot commented Jun 18, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

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

⚙️ sentry-android Build Distribution Settings

@github-actions

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 345.44 ms 406.43 ms 60.99 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
a416a65 333.78 ms 410.37 ms 76.59 ms
d15471f 304.55 ms 408.43 ms 103.87 ms
ca6b6d8 380.45 ms 460.38 ms 79.93 ms
c8125f3 397.65 ms 485.14 ms 87.49 ms
b936425 302.69 ms 372.86 ms 70.17 ms
ed33deb 334.19 ms 362.30 ms 28.11 ms
cf708bd 408.35 ms 458.98 ms 50.63 ms
eb95ded 317.51 ms 369.08 ms 51.57 ms
a5ab36f 320.47 ms 389.77 ms 69.30 ms
80fd6ad 321.06 ms 375.79 ms 54.73 ms

App size

Revision Plain With Sentry Diff
a416a65 1.58 MiB 2.12 MiB 555.26 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
ca6b6d8 0 B 0 B 0 B
c8125f3 1.58 MiB 2.10 MiB 532.32 KiB
b936425 0 B 0 B 0 B
ed33deb 1.58 MiB 2.13 MiB 559.52 KiB
cf708bd 1.58 MiB 2.11 MiB 539.71 KiB
eb95ded 0 B 0 B 0 B
a5ab36f 1.58 MiB 2.12 MiB 555.26 KiB
80fd6ad 0 B 0 B 0 B

try {
return call.call();
} catch (LinkageError e) {
return fallback.call(e);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note that we're not logging. Three reasons for that:

  1. Falling back when the method isn't present is correct behavior and expected from the consumer's side in cases where there's a default implementation for the method and our fallback matches its behavior (this will almost always be the case).
  2. Wiring a logger through this Java API would make it even more ungainly.
  3. Callers can always log themselves via the Fallback lambda.

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