Skip to content

Commit

Permalink
enh: cache parsed dsn (#2365)
Browse files Browse the repository at this point in the history
* add cached dsn

* update

* update

* update

* update

* update CHANGELOG

* update

* re-evaluate when dsn is set

* update comment
  • Loading branch information
buenaflor authored Oct 22, 2024
1 parent 136c365 commit 8f95e33
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 12 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Enhancements

- Cache parsed DSN ([#2365](https://github.com/getsentry/sentry-dart/pull/2365))

## 8.10.0-beta.2

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion dart/lib/src/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class Sentry {
}

// try parsing the dsn
Dsn.parse(options.dsn!);
options.parsedDsn;

return true;
}
Expand Down
4 changes: 1 addition & 3 deletions dart/lib/src/sentry_baggage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,7 @@ class SentryBaggage {
setValuesFromScope(Scope scope, SentryOptions options) {
final propagationContext = scope.propagationContext;
setTraceId(propagationContext.traceId.toString());
if (options.dsn != null) {
setPublicKey(Dsn.parse(options.dsn!).publicKey);
}
setPublicKey(options.parsedDsn.publicKey);
if (options.release != null) {
setRelease(options.release!);
}
Expand Down
34 changes: 30 additions & 4 deletions dart/lib/src/sentry_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,34 @@ class SentryOptions {
/// Default Log level if not specified Default is DEBUG
static final SentryLevel _defaultDiagnosticLevel = SentryLevel.debug;

/// The DSN tells the SDK where to send the events to. If an empty string is
/// used, the SDK will not send any events.
String? dsn;
String? _dsn;
Dsn? _parsedDsn;

/// The DSN tells the SDK where to send the events to.
/// If an empty string is used, the SDK will not send any events.
String? get dsn => _dsn;

set dsn(String? value) {
if (_dsn != value) {
_dsn = value;
_parsedDsn = null; // Invalidate the cached parsed DSN
}
}

/// Evaluates and parses the DSN.
/// May throw an exception if the DSN is invalid.
@internal
Dsn get parsedDsn {
_parsedDsn ??= _parseDsn();
return _parsedDsn!;
}

Dsn _parseDsn() {
if (_dsn == null || _dsn!.isEmpty) {
throw StateError('DSN is null or empty');
}
return Dsn.parse(_dsn!);
}

/// If [compressPayload] is `true` the outgoing HTTP payloads are compressed
/// using gzip. Otherwise, the payloads are sent in plain UTF8-encoded JSON
Expand Down Expand Up @@ -525,7 +550,8 @@ class SentryOptions {
/// iOS only supports http proxies, while macOS also supports socks.
SentryProxy? proxy;

SentryOptions({this.dsn, PlatformChecker? checker}) {
SentryOptions({String? dsn, PlatformChecker? checker}) {
this.dsn = dsn;
if (checker != null) {
platformChecker = checker;
}
Expand Down
2 changes: 1 addition & 1 deletion dart/lib/src/sentry_tracer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class SentryTracer extends ISentrySpan {

_sentryTraceContextHeader = SentryTraceContextHeader(
_rootSpan.context.traceId,
Dsn.parse(_hub.options.dsn!).publicKey,
_hub.options.parsedDsn.publicKey,
release: _hub.options.release,
environment: _hub.options.environment,
userId: null, // because of PII not sending it for now
Expand Down
4 changes: 2 additions & 2 deletions dart/lib/src/transport/http_transport.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class HttpTransport implements Transport {
}

HttpTransport._(this._options, this._rateLimiter)
: _requestHandler = HttpTransportRequestHandler(
_options, Dsn.parse(_options.dsn!).postUri);
: _requestHandler =
HttpTransportRequestHandler(_options, _options.parsedDsn.postUri);

@override
Future<SentryId?> send(SentryEnvelope envelope) async {
Expand Down
2 changes: 1 addition & 1 deletion dart/lib/src/transport/http_transport_request_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class HttpTransportRequestHandler {
late _CredentialBuilder _credentialBuilder;

HttpTransportRequestHandler(this._options, this._requestUri)
: _dsn = Dsn.parse(_options.dsn!),
: _dsn = _options.parsedDsn,
_headers = _buildHeaders(
_options.platformChecker.isWeb,
_options.sentryClientName,
Expand Down
33 changes: 33 additions & 0 deletions dart/test/sentry_options_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,37 @@ void main() {

expect(options.enableDartSymbolication, true);
});

test('parsedDsn is correctly parsed and cached', () {
final options = defaultTestOptions();

// Access parsedDsn for the first time
final parsedDsn1 = options.parsedDsn;

// Access parsedDsn again
final parsedDsn2 = options.parsedDsn;

// Should return the same instance since it's cached
expect(identical(parsedDsn1, parsedDsn2), isTrue);

// Verify the parsed DSN fields
final manuallyParsedDsn = Dsn.parse(options.dsn!);
expect(parsedDsn1.publicKey, manuallyParsedDsn.publicKey);
expect(parsedDsn1.postUri, manuallyParsedDsn.postUri);
expect(parsedDsn1.secretKey, manuallyParsedDsn.secretKey);
expect(parsedDsn1.projectId, manuallyParsedDsn.projectId);
expect(parsedDsn1.uri, manuallyParsedDsn.uri);
});

test('parsedDsn throws when DSN is null', () {
final options = defaultTestOptions()..dsn = null;

expect(() => options.parsedDsn, throwsA(isA<StateError>()));
});

test('parsedDsn throws when DSN is empty', () {
final options = defaultTestOptions()..dsn = '';

expect(() => options.parsedDsn, throwsA(isA<StateError>()));
});
}

0 comments on commit 8f95e33

Please sign in to comment.