chore(util): Add CompileOnlyCompat for compile-only linkage errors#5565
Open
0xadam-brown wants to merge 1 commit into
Open
chore(util): Add CompileOnlyCompat for compile-only linkage errors#55650xadam-brown wants to merge 1 commit into
0xadam-brown wants to merge 1 commit into
Conversation
…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.
📲 Install BuildsAndroid
|
Contributor
Performance metrics 🚀
|
| 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 |
0xadam-brown
commented
Jun 18, 2026
| try { | ||
| return call.call(); | ||
| } catch (LinkageError e) { | ||
| return fallback.call(e); |
Member
Author
There was a problem hiding this comment.
Note that we're not logging. Three reasons for that:
- 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).
- Wiring a logger through this Java API would make it even more ungainly.
- Callers can always log themselves via the
Fallbacklambda.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
compileOnlydependencies 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 usetry-catchblocks when calling those methods. The utilities introduced here help us raise awareness about the issue and centralize our approach.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
sentrymodule. 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-catchlogic into a method requires using lambdas / SAMs, and that means an additional object allocation relative to an inlinetry-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
sendDefaultPIIis enabled.🔮 Next steps