Skip to content

Commit 8f95e33

Browse files
authored
enh: cache parsed dsn (#2365)
* add cached dsn * update * update * update * update * update CHANGELOG * update * re-evaluate when dsn is set * update comment
1 parent 136c365 commit 8f95e33

8 files changed

+75
-12
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Enhancements
6+
7+
- Cache parsed DSN ([#2365](https://github.com/getsentry/sentry-dart/pull/2365))
8+
39
## 8.10.0-beta.2
410

511
### Fixes

dart/lib/src/sentry.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class Sentry {
273273
}
274274

275275
// try parsing the dsn
276-
Dsn.parse(options.dsn!);
276+
options.parsedDsn;
277277

278278
return true;
279279
}

dart/lib/src/sentry_baggage.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,7 @@ class SentryBaggage {
9595
setValuesFromScope(Scope scope, SentryOptions options) {
9696
final propagationContext = scope.propagationContext;
9797
setTraceId(propagationContext.traceId.toString());
98-
if (options.dsn != null) {
99-
setPublicKey(Dsn.parse(options.dsn!).publicKey);
100-
}
98+
setPublicKey(options.parsedDsn.publicKey);
10199
if (options.release != null) {
102100
setRelease(options.release!);
103101
}

dart/lib/src/sentry_options.dart

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,34 @@ class SentryOptions {
2323
/// Default Log level if not specified Default is DEBUG
2424
static final SentryLevel _defaultDiagnosticLevel = SentryLevel.debug;
2525

26-
/// The DSN tells the SDK where to send the events to. If an empty string is
27-
/// used, the SDK will not send any events.
28-
String? dsn;
26+
String? _dsn;
27+
Dsn? _parsedDsn;
28+
29+
/// The DSN tells the SDK where to send the events to.
30+
/// If an empty string is used, the SDK will not send any events.
31+
String? get dsn => _dsn;
32+
33+
set dsn(String? value) {
34+
if (_dsn != value) {
35+
_dsn = value;
36+
_parsedDsn = null; // Invalidate the cached parsed DSN
37+
}
38+
}
39+
40+
/// Evaluates and parses the DSN.
41+
/// May throw an exception if the DSN is invalid.
42+
@internal
43+
Dsn get parsedDsn {
44+
_parsedDsn ??= _parseDsn();
45+
return _parsedDsn!;
46+
}
47+
48+
Dsn _parseDsn() {
49+
if (_dsn == null || _dsn!.isEmpty) {
50+
throw StateError('DSN is null or empty');
51+
}
52+
return Dsn.parse(_dsn!);
53+
}
2954

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

528-
SentryOptions({this.dsn, PlatformChecker? checker}) {
553+
SentryOptions({String? dsn, PlatformChecker? checker}) {
554+
this.dsn = dsn;
529555
if (checker != null) {
530556
platformChecker = checker;
531557
}

dart/lib/src/sentry_tracer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ class SentryTracer extends ISentrySpan {
377377

378378
_sentryTraceContextHeader = SentryTraceContextHeader(
379379
_rootSpan.context.traceId,
380-
Dsn.parse(_hub.options.dsn!).publicKey,
380+
_hub.options.parsedDsn.publicKey,
381381
release: _hub.options.release,
382382
environment: _hub.options.environment,
383383
userId: null, // because of PII not sending it for now

dart/lib/src/transport/http_transport.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class HttpTransport implements Transport {
3030
}
3131

3232
HttpTransport._(this._options, this._rateLimiter)
33-
: _requestHandler = HttpTransportRequestHandler(
34-
_options, Dsn.parse(_options.dsn!).postUri);
33+
: _requestHandler =
34+
HttpTransportRequestHandler(_options, _options.parsedDsn.postUri);
3535

3636
@override
3737
Future<SentryId?> send(SentryEnvelope envelope) async {

dart/lib/src/transport/http_transport_request_handler.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class HttpTransportRequestHandler {
1717
late _CredentialBuilder _credentialBuilder;
1818

1919
HttpTransportRequestHandler(this._options, this._requestUri)
20-
: _dsn = Dsn.parse(_options.dsn!),
20+
: _dsn = _options.parsedDsn,
2121
_headers = _buildHeaders(
2222
_options.platformChecker.isWeb,
2323
_options.sentryClientName,

dart/test/sentry_options_test.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,37 @@ void main() {
198198

199199
expect(options.enableDartSymbolication, true);
200200
});
201+
202+
test('parsedDsn is correctly parsed and cached', () {
203+
final options = defaultTestOptions();
204+
205+
// Access parsedDsn for the first time
206+
final parsedDsn1 = options.parsedDsn;
207+
208+
// Access parsedDsn again
209+
final parsedDsn2 = options.parsedDsn;
210+
211+
// Should return the same instance since it's cached
212+
expect(identical(parsedDsn1, parsedDsn2), isTrue);
213+
214+
// Verify the parsed DSN fields
215+
final manuallyParsedDsn = Dsn.parse(options.dsn!);
216+
expect(parsedDsn1.publicKey, manuallyParsedDsn.publicKey);
217+
expect(parsedDsn1.postUri, manuallyParsedDsn.postUri);
218+
expect(parsedDsn1.secretKey, manuallyParsedDsn.secretKey);
219+
expect(parsedDsn1.projectId, manuallyParsedDsn.projectId);
220+
expect(parsedDsn1.uri, manuallyParsedDsn.uri);
221+
});
222+
223+
test('parsedDsn throws when DSN is null', () {
224+
final options = defaultTestOptions()..dsn = null;
225+
226+
expect(() => options.parsedDsn, throwsA(isA<StateError>()));
227+
});
228+
229+
test('parsedDsn throws when DSN is empty', () {
230+
final options = defaultTestOptions()..dsn = '';
231+
232+
expect(() => options.parsedDsn, throwsA(isA<StateError>()));
233+
});
201234
}

0 commit comments

Comments
 (0)