Skip to content

Commit

Permalink
Merge branch 'main' into feat/redact-screenshots-via-view-hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
martinhaintz authored Oct 24, 2024
2 parents 0969b7b + 8f95e33 commit 73a4224
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/flutter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
- uses: actions/setup-java@v4
if: ${{ matrix.target == 'android' }}
with:
java-version: '11'
java-version: '17'
distribution: 'adopt'

# Install required dependencies for Flutter on Linux on Ubuntu
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

### Enhancements

- Cache parsed DSN ([#2365](https://github.com/getsentry/sentry-dart/pull/2365))
- Switching from traditional screenshot to view hierarchy for screenshots which allows redacting ([#2361](https://github.com/getsentry/sentry-dart/pull/2361))

## 8.10.0-beta.2
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>()));
});
}
1 change: 1 addition & 0 deletions flutter/example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ apply plugin: 'com.ydq.android.gradle.native-aar.import'
// apply plugin: 'io.sentry.android.gradle'

android {
namespace = "io.sentry.samples.flutter"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
Expand Down
3 changes: 2 additions & 1 deletion flutter/example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:exported="true">
android:exported="true"
android:networkSecurityConfig="@xml/network">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
Expand Down
6 changes: 3 additions & 3 deletions flutter/example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ buildscript {
}

dependencies {
classpath 'io.sentry:sentry-android-gradle-plugin:4.5.0'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'io.sentry:sentry-android-gradle-plugin:4.12.0'
classpath 'com.android.tools.build:gradle:8.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'io.github.howardpang:androidNativeBundle:1.1.3'
}
Expand All @@ -26,7 +26,7 @@ subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
project.evaluationDependsOn(":app")
}

tasks.register("clean", Delete) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Wed Oct 16 15:46:36 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 1 addition & 1 deletion flutter/example/lib/isar/user.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
Future.delayed(const Duration(seconds: 3), () {
SentryFlutter.reportFullyDisplayed();
});
return feedback.BetterFeedback(
child: ChangeNotifierProvider<ThemeProvider>(
create: (_) => ThemeProvider(),
Expand Down Expand Up @@ -231,7 +234,7 @@ class MainScaffold extends StatelessWidget {
TooltipButton(
onPressed: isarTest,
text:
'Executes CRUD operations on an in-memory with Isart and sends the created transaction to Sentry.',
'Executes CRUD operations on an in-memory with Isar and sends the created transaction to Sentry.',
buttonTitle: 'isar',
),
TooltipButton(
Expand Down
10 changes: 10 additions & 0 deletions flutter/example/pubspec_overrides.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ dependency_overrides:
path: ../../drift
sentry_isar:
path: ../../isar
# isar community fork is more stable
isar:
version: ^3.1.0
hosted: https://pub.isar-community.dev/
isar_flutter_libs:
version: ^3.1.0
hosted: https://pub.isar-community.dev/
isar_generator:
version: ^3.1.0
hosted: https://pub.isar-community.dev/

0 comments on commit 73a4224

Please sign in to comment.