perf: Replace java.net.URI with custom string parsing in Dsn (#5448)
* perf: Replace java.net.URI with custom string parsing in Dsn
The Dsn constructor used `new URI(dsnString).normalize()` to parse the
DSN string, which is known to be slow on Android. Since `retrieveParsedDsn()`
is called on the main thread during `Sentry.init()` via
`preInitConfigurations()`, this directly impacts app startup time.
Replace the URI-based parsing with manual indexOf/substring operations.
The only remaining URI construction is from pre-parsed components
(`new URI(scheme, null, host, port, path, null, null)`), which is
significantly cheaper since the JDK doesn't need to re-parse a string.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: Add tests for custom DSN string parsing
Cover edge cases specific to the manual indexOf/substring parser:
null input, missing scheme separator, no slash after host, multiple
path segments, port with path, multiple double slashes, query string
with port, empty secret key, and a realistic Sentry DSN with org id.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* changelog: Add entry for custom DSN parser
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(dsn): Strip URI fragments and support IPv6 hosts
Harden the custom DSN parser and convert its tests to Google Truth.
- Strip URI fragments (#...) alongside query strings so they no longer
leak into the project id and corrupt the constructed Sentry URI.
- Detect bracketed IPv6 literal hosts when locating the port separator,
restoring behavior that java.net.URI handled.
- Narrow the parse error handling from catch (Throwable) to the
expected exceptions, which stops swallowing Error and removes the
doubled exception message.
- Extract the parsing steps into focused private helpers.
- Convert DsnTest to Google Truth assertions.
- Move the changelog entry to the Unreleased section, since 8.43.0 and
8.43.1 have already been released.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test(dsn): Assert exception messages via Truth hasMessageThat
Follow Truth's recommended pattern for exception testing: catch with
assertFailsWith, then assert on the caught throwable with
assertThat(ex).hasMessageThat(). Also assert the message in the
previously bare throw-only cases so they can no longer pass on an
unrelated exception.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(dsn): Give a clear error message for a malformed port
Parse the port in a dedicated helper that reports the offending value
("Invalid DSN: Invalid port 'abc'.") instead of leaking the raw
NumberFormatException text. Narrow the catch to URISyntaxException now
that the port is the only parseInt, and add a test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> N
Nelson Osacky committed
29f120b097b4bd6c870491f5dc35caf7b37a7609
Parent: 105d667
Committed by GitHub <noreply@github.com>
on 6/9/2026, 8:22:41 AM