SIGN IN SIGN UP

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