diff --git a/.craft.yml b/.craft.yml index ac5e86e3c7..5ff7ad5d33 100644 --- a/.craft.yml +++ b/.craft.yml @@ -25,5 +25,4 @@ targets: pub:sentry_sqflite: pub:sentry_drift: pub:sentry_hive: - # Initial release on pub.dev needed first before uncommenting - # pub:sentry_isar: + pub:sentry_isar: diff --git a/.github/workflows/flutter_integration_test.yml b/.github/workflows/flutter_integration_test.yml new file mode 100644 index 0000000000..86bcb2e2dd --- /dev/null +++ b/.github/workflows/flutter_integration_test.yml @@ -0,0 +1,119 @@ +name: flutter integration tests +on: + # Currently broken, enable after fixing + workflow_dispatch + # push: + # branches: + # - main + # - release/** + # pull_request: + # paths-ignore: +# - 'file/**' + +jobs: + cancel-previous-workflow: + runs-on: ubuntu-latest + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # pin@0.11.0 + with: + access_token: ${{ github.token }} + + test-android: + runs-on: macos-latest + timeout-minutes: 30 + defaults: + run: + working-directory: ./flutter/example + strategy: + fail-fast: false + matrix: + sdk: [ "stable", "beta" ] + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: actions/setup-java@v3 + with: + distribution: "adopt" + java-version: "11" + + - uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa # pin@v2.10.0 + with: + channel: ${{ matrix.sdk }} + + - name: flutter upgrade + run: flutter upgrade + + - name: flutter pub get + run: flutter pub get + + - name: Gradle cache + uses: gradle/gradle-build-action@982da8e78c05368c70dac0351bb82647a9e9a5d2 # pin@v2.11.1 + + - name: AVD cache + uses: actions/cache@v3 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-21 + + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b #pin@v2.28.0 + with: + working-directory: ./flutter/example + api-level: 21 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + arch: x86_64 + profile: Nexus 6 + script: echo 'Generated AVD snapshot for caching.' + + - name: launch android emulator & run android integration test + uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b #pin@v2.28.0 + with: + working-directory: ./flutter/example + api-level: 21 + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + arch: x86_64 + profile: Nexus 6 + script: flutter test integration_test/integration_test.dart --verbose + + test-ios: + runs-on: macos-13 + timeout-minutes: 30 + defaults: + run: + working-directory: ./flutter/example + strategy: + fail-fast: false + matrix: + # 'beta' is flaky because of https://github.com/flutter/flutter/issues/124340 + sdk: [ "stable" ] + steps: + - name: checkout + uses: actions/checkout@v3 + + - uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa # pin@v2.10.0 + with: + channel: ${{ matrix.sdk }} + + - name: flutter upgrade + run: flutter upgrade + + - name: flutter pub get + run: flutter pub get + + - name: launch ios simulator + run: | + simulator_id=$(xcrun simctl create sentryPhone com.apple.CoreSimulator.SimDeviceType.iPhone-14 com.apple.CoreSimulator.SimRuntime.iOS-16-2) + xcrun simctl boot ${simulator_id} + + - name: run ios integration test + run: flutter test integration_test/integration_test.dart --verbose diff --git a/.github/workflows/flutter_test.yml b/.github/workflows/flutter_test.yml index e6d845bb72..0f3e9369b4 100644 --- a/.github/workflows/flutter_test.yml +++ b/.github/workflows/flutter_test.yml @@ -54,7 +54,7 @@ jobs: run: flutter pub get - name: Gradle cache - uses: gradle/gradle-build-action@8baac4c8ef753599f92eeb509c246d09d6250fa6 + uses: gradle/gradle-build-action@8baac4c8ef753599f92eeb509c246d09d6250fa6 # pin@v3.0.0 - name: AVD cache uses: actions/cache@v4 @@ -120,8 +120,7 @@ jobs: fail-fast: false matrix: sdk: ["stable", "beta"] - # TODO: remove ios for now, will be fixed in v8 - target: ["macos"] + target: ["ios", "macos"] steps: - name: checkout uses: actions/checkout@v4 diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml new file mode 100644 index 0000000000..3e05b6afbb --- /dev/null +++ b/.github/workflows/testflight.yml @@ -0,0 +1,57 @@ +name: Upload to Testflight +on: + push: + branches: + - main + - release/** + pull_request: + paths: + - '.github/workflows/testflight.yml' + +jobs: + upload_to_testflight: + name: Build and Upload to Testflight + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + - uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa # pin@v2.10.0 + - run: xcodes select 15.0.1 + - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # pin@v1.152.0 + with: + ruby-version: '2.7.5' + bundler-cache: true + + - name: flutter + working-directory: ./flutter/example + run: | + flutter upgrade + flutter pub get + flutter build ios --no-codesign + + - name: Install Fastlane + working-directory: ./flutter/example/ios + run: bundle install + + - name: Bump, Build & Upload App to TestFlight + working-directory: ./flutter/example/ios + env: + APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }} + APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }} + APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }} + FASTLANE_BUNDLE_VERSION: ${{ github.run_number }} + FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }} + MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_LOG_LEVEL: DEBUG + run: | + bundle exec fastlane bump_build_number + bundle exec fastlane build_release + bundle exec fastlane upload_testflight + + - name: Upload Symbols to Sentry + working-directory: ./flutter/example + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + run: flutter packages pub run sentry_dart_plugin \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dbc1dd7d2..8acd561d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## Unreleased + +This release contains breaking changes, please read the changelog carefully. + +*Changes from the latest v7 release are included in this major release* + +### Breaking Changes + +- Bump iOS minimum deployment target from **11** to **12** ([#1821](https://github.com/getsentry/sentry-dart/pull/1821)) +- Mark exceptions not handled by the user as `handled: false` ([#1535](https://github.com/getsentry/sentry-dart/pull/1535)) + - This will affect your release health data, and is therefore considered a breaking change. +- Refrain from overwriting the span status for unfinished spans ([#1577](https://github.com/getsentry/sentry-dart/pull/1577)) + - Older self-hosted sentry instances will drop transactions containing unfinished spans. + - This change was introduced in [relay/#1690](https://github.com/getsentry/relay/pull/1690) and released with [22.12.0](https://github.com/getsentry/relay/releases/tag/22.12.0) +- Do not leak extensions of external classes ([#1576](https://github.com/getsentry/sentry-dart/pull/1576)) +- Make `hint` non-nullable in `BeforeSendCallback`, `BeforeBreadcrumbCall` and `EventProcessor` ([#1574](https://github.com/getsentry/sentry-dart/pull/1574)) + - This will affect your callbacks, making this a breaking change. +- Load Device Contexts from Sentry Java ([#1616](https://github.com/getsentry/sentry-dart/pull/1616)) + - Now the device context from Android is available in `BeforeSendCallback` +- Set ip_address to {{auto}} by default, even if sendDefaultPII is disabled ([#1665](https://github.com/getsentry/sentry-dart/pull/1665)) + - Instead use the "Prevent Storing of IP Addresses" option in the "Security & Privacy" project settings on sentry.io + +### Features + +- Add support for exception aggregates ([#1866](https://github.com/getsentry/sentry-dart/pull/1866)) + ## 7.20.0 ### Build @@ -117,6 +143,40 @@ - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8200) - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.19.0...8.20.0) +## 8.0.0-beta.2 + +### Breaking Changes + +- Bump iOS minimum deployment target from **11** to **12** ([#1821](https://github.com/getsentry/sentry-dart/pull/1821)) +- Mark exceptions not handled by the user as `handled: false` ([#1535](https://github.com/getsentry/sentry-dart/pull/1535)) + - This will affect your release health data, and is therefore considered a breaking change. +- Refrain from overwriting the span status for unfinished spans ([#1577](https://github.com/getsentry/sentry-dart/pull/1577)) + - Older self-hosted sentry instances will drop transactions containing unfinished spans. + - This change was introduced in [relay/#1690](https://github.com/getsentry/relay/pull/1690) and released with [22.12.0](https://github.com/getsentry/relay/releases/tag/22.12.0) +- Do not leak extensions of external classes ([#1576](https://github.com/getsentry/sentry-dart/pull/1576)) +- Make `hint` non-nullable in `BeforeSendCallback`, `BeforeBreadcrumbCall` and `EventProcessor` ([#1574](https://github.com/getsentry/sentry-dart/pull/1574)) + - This will affect your callbacks, making this a breaking change. +- Load Device Contexts from Sentry Java ([#1616](https://github.com/getsentry/sentry-dart/pull/1616)) + - Now the device context from Android is available in `BeforeSendCallback` +- Set ip_address to {{auto}} by default, even if sendDefaultPII is disabled ([#1665](https://github.com/getsentry/sentry-dart/pull/1665)) + - Instead use the "Prevent Storing of IP Addresses" option in the "Security & Privacy" project settings on sentry.io + +### Fixes + +- Remove Flutter dependency from Drift integration ([#1867](https://github.com/getsentry/sentry-dart/pull/1867)) +- Remove dead code, cold start bool is now always present ([#1861](https://github.com/getsentry/sentry-dart/pull/1861)) +- Fix iOS "Arithmetic Overflow" ([#1874](https://github.com/getsentry/sentry-dart/pull/1874)) + +### Dependencies + +- Bump Cocoa SDK from v8.19.0 to v8.20.0 ([#1856](https://github.com/getsentry/sentry-dart/pull/1856)) + - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8200) + - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.19.0...8.20.0) + +## 8.0.0-beta.1 + +This release is replaced by `8.0.0-beta.2` + ## 7.16.0 ### Features diff --git a/dart/README.md b/dart/README.md index e3cf3b6bb6..a6582faa16 100644 --- a/dart/README.md +++ b/dart/README.md @@ -184,8 +184,11 @@ Read more about [Automatic Instrumentation](https://docs.sentry.io/platforms/dar #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +#### Resources + +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) -* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) +* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) \ No newline at end of file diff --git a/dart/example/bin/example.dart b/dart/example/bin/example.dart index 5163f341f7..d7530f5874 100644 --- a/dart/example/bin/example.dart +++ b/dart/example/bin/example.dart @@ -104,7 +104,7 @@ Future decode() async { class TagEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {hint}) { + SentryEvent? apply(SentryEvent event, hint) { return event..tags?.addAll({'page-locale': 'en-us'}); } } diff --git a/dart/example_web/analysis_options.yaml b/dart/example_web/analysis_options.yaml new file mode 100644 index 0000000000..be16ace7d1 --- /dev/null +++ b/dart/example_web/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:lints/recommended.yaml + +analyzer: + errors: + path_does_not_exist: ignore diff --git a/dart/example_web/pubspec.yaml b/dart/example_web/pubspec.yaml index 2363aa83bb..7bcb64d06e 100644 --- a/dart/example_web/pubspec.yaml +++ b/dart/example_web/pubspec.yaml @@ -8,7 +8,7 @@ environment: dependencies: sentry: - path: ../../dart + path: ../../dart/ dev_dependencies: build_runner: ^2.4.2 diff --git a/dart/example_web/web/main.dart b/dart/example_web/web/main.dart index c396be5e83..3034effe9b 100644 --- a/dart/example_web/web/main.dart +++ b/dart/example_web/web/main.dart @@ -129,7 +129,7 @@ Future parseData() async { class TagEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { return event..tags?.addAll({'page-locale': 'en-us'}); } } diff --git a/dart/lib/src/client_reports/discard_reason.dart b/dart/lib/src/client_reports/discard_reason.dart index 1b990f8dd2..81c3a45dd0 100644 --- a/dart/lib/src/client_reports/discard_reason.dart +++ b/dart/lib/src/client_reports/discard_reason.dart @@ -12,24 +12,3 @@ enum DiscardReason { cacheOverflow, rateLimitBackoff, } - -extension OutcomeExtension on DiscardReason { - String toStringValue() { - switch (this) { - case DiscardReason.beforeSend: - return 'before_send'; - case DiscardReason.eventProcessor: - return 'event_processor'; - case DiscardReason.sampleRate: - return 'sample_rate'; - case DiscardReason.networkError: - return 'network_error'; - case DiscardReason.queueOverflow: - return 'queue_overflow'; - case DiscardReason.cacheOverflow: - return 'cache_overflow'; - case DiscardReason.rateLimitBackoff: - return 'ratelimit_backoff'; - } - } -} diff --git a/dart/lib/src/client_reports/discarded_event.dart b/dart/lib/src/client_reports/discarded_event.dart index 0b989aa4cf..01caa31ca2 100644 --- a/dart/lib/src/client_reports/discarded_event.dart +++ b/dart/lib/src/client_reports/discarded_event.dart @@ -13,9 +13,55 @@ class DiscardedEvent { Map toJson() { return { - 'reason': reason.toStringValue(), - 'category': category.toStringValue(), + 'reason': reason._toStringValue(), + 'category': category._toStringValue(), 'quantity': quantity, }; } } + +extension _OutcomeExtension on DiscardReason { + String _toStringValue() { + switch (this) { + case DiscardReason.beforeSend: + return 'before_send'; + case DiscardReason.eventProcessor: + return 'event_processor'; + case DiscardReason.sampleRate: + return 'sample_rate'; + case DiscardReason.networkError: + return 'network_error'; + case DiscardReason.queueOverflow: + return 'queue_overflow'; + case DiscardReason.cacheOverflow: + return 'cache_overflow'; + case DiscardReason.rateLimitBackoff: + return 'ratelimit_backoff'; + } + } +} + +extension _DataCategoryExtension on DataCategory { + String _toStringValue() { + switch (this) { + case DataCategory.all: + return '__all__'; + case DataCategory.dataCategoryDefault: + return 'default'; + case DataCategory.error: + return 'error'; + case DataCategory.session: + return 'session'; + case DataCategory.transaction: + return 'transaction'; + case DataCategory.attachment: + return 'attachment'; + case DataCategory.security: + return 'security'; + case DataCategory.unknown: + return 'unknown'; + case DataCategory.metricBucket: + return 'metric_bucket'; + } + } +} diff --git a/dart/lib/src/event_processor.dart b/dart/lib/src/event_processor.dart index 94fcd77fd8..45005d7b0e 100644 --- a/dart/lib/src/event_processor.dart +++ b/dart/lib/src/event_processor.dart @@ -8,7 +8,7 @@ import 'protocol.dart'; /// null in case the event will be dropped and not sent. abstract class EventProcessor { FutureOr apply( - SentryEvent event, { - Hint? hint, - }); + SentryEvent event, + Hint hint, + ); } diff --git a/dart/lib/src/event_processor/deduplication_event_processor.dart b/dart/lib/src/event_processor/deduplication_event_processor.dart index 5c3bd4606e..8706082cf5 100644 --- a/dart/lib/src/event_processor/deduplication_event_processor.dart +++ b/dart/lib/src/event_processor/deduplication_event_processor.dart @@ -26,7 +26,7 @@ class DeduplicationEventProcessor implements EventProcessor { final SentryOptions _options; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { if (event is SentryTransaction) { return event; } diff --git a/dart/lib/src/event_processor/enricher/io_enricher_event_processor.dart b/dart/lib/src/event_processor/enricher/io_enricher_event_processor.dart index 47e3481144..52243a8572 100644 --- a/dart/lib/src/event_processor/enricher/io_enricher_event_processor.dart +++ b/dart/lib/src/event_processor/enricher/io_enricher_event_processor.dart @@ -16,7 +16,7 @@ class IoEnricherEventProcessor implements EnricherEventProcessor { final SentryOptions _options; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { // If there's a native integration available, it probably has better // information available than Flutter. diff --git a/dart/lib/src/event_processor/enricher/web_enricher_event_processor.dart b/dart/lib/src/event_processor/enricher/web_enricher_event_processor.dart index f7681eeeaf..e51cff4b71 100644 --- a/dart/lib/src/event_processor/enricher/web_enricher_event_processor.dart +++ b/dart/lib/src/event_processor/enricher/web_enricher_event_processor.dart @@ -21,7 +21,7 @@ class WebEnricherEventProcessor implements EnricherEventProcessor { final SentryOptions _options; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { // Web has no native integration, so no need to check for it final contexts = event.contexts.copyWith( diff --git a/dart/lib/src/event_processor/exception/io_exception_event_processor.dart b/dart/lib/src/event_processor/exception/io_exception_event_processor.dart index 0f7763f35e..bb4049c00e 100644 --- a/dart/lib/src/event_processor/exception/io_exception_event_processor.dart +++ b/dart/lib/src/event_processor/exception/io_exception_event_processor.dart @@ -14,7 +14,7 @@ class IoExceptionEventProcessor implements ExceptionEventProcessor { final SentryOptions _options; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { final throwable = event.throwable; if (throwable is HttpException) { return _applyHttpException(throwable, event); diff --git a/dart/lib/src/event_processor/exception/web_exception_event_processor.dart b/dart/lib/src/event_processor/exception/web_exception_event_processor.dart index ad57c9f5c2..6ce3be0fe0 100644 --- a/dart/lib/src/event_processor/exception/web_exception_event_processor.dart +++ b/dart/lib/src/event_processor/exception/web_exception_event_processor.dart @@ -8,5 +8,5 @@ ExceptionEventProcessor exceptionEventProcessor(SentryOptions _) => class WebExcptionEventProcessor implements ExceptionEventProcessor { @override - SentryEvent apply(SentryEvent event, {Hint? hint}) => event; + SentryEvent apply(SentryEvent event, Hint hint) => event; } diff --git a/dart/lib/src/hint.dart b/dart/lib/src/hint.dart index 41ea7a0deb..9df1b38365 100644 --- a/dart/lib/src/hint.dart +++ b/dart/lib/src/hint.dart @@ -12,8 +12,8 @@ import 'sentry_options.dart'; /// Example: /// /// ```dart -/// options.beforeSend = (event, {hint}) { -/// final syntheticException = hint?.get(TypeCheckHint.syntheticException); +/// options.beforeSend = (event, hint) { +/// final syntheticException = hint.get(TypeCheckHint.syntheticException); /// if (syntheticException is FlutterErrorDetails) { /// // Do something with hint data /// } @@ -29,14 +29,14 @@ import 'sentry_options.dart'; /// ```dart /// import 'dart:convert'; /// -/// options.beforeSend = (event, {hint}) { +/// options.beforeSend = (event, hint) { /// final text = 'This event should not be sent happen in prod. Investigate.'; /// final textAttachment = SentryAttachment.fromIntList( /// utf8.encode(text), /// 'event_info.txt', /// contentType: 'text/plain', /// ); -/// hint?.attachments.add(textAttachment); +/// hint.attachments.add(textAttachment); /// return event; /// }; /// ``` diff --git a/dart/lib/src/http_client/failed_request_client.dart b/dart/lib/src/http_client/failed_request_client.dart index dc07f407ed..446b88826c 100644 --- a/dart/lib/src/http_client/failed_request_client.dart +++ b/dart/lib/src/http_client/failed_request_client.dart @@ -138,7 +138,7 @@ class FailedRequestClient extends BaseClient { // Only check `failedRequestStatusCodes` & `failedRequestTargets` if no exception was thrown. if (exception == null) { - if (!failedRequestStatusCodes.containsStatusCode(statusCode)) { + if (!failedRequestStatusCodes._containsStatusCode(statusCode)) { return; } if (!containsTargetOrMatchesRegExp( @@ -249,7 +249,7 @@ class FailedRequestClient extends BaseClient { } extension _ListX on List { - bool containsStatusCode(int? statusCode) { + bool _containsStatusCode(int? statusCode) { if (statusCode == null) { return false; } diff --git a/dart/lib/src/protocol/mechanism.dart b/dart/lib/src/protocol/mechanism.dart index 2c06c954f6..22a6356800 100644 --- a/dart/lib/src/protocol/mechanism.dart +++ b/dart/lib/src/protocol/mechanism.dart @@ -44,6 +44,38 @@ class Mechanism { /// This may be because they are created at a central place (like a crash handler), and are all called the same: Error, Segfault etc. When the flag is set, Sentry will then try to use other information (top in-app frame function) rather than exception type and value in the UI for the primary event display. This flag should be set for all "segfaults" for instance as every single error group would look very similar otherwise. final bool? synthetic; + /// An optional boolean value, set `true` when the exception is the exception + /// group type specific to the platform or language. + /// The default is false when omitted. + /// For example, exceptions of type [PlatformException](https://api.flutter.dev/flutter/services/PlatformException-class.html) + /// have set it to `true`, others are set to `false`. + final bool? isExceptionGroup; + + /// An optional string value describing the source of the exception. + /// + /// The SDK should populate this with the name of the property or attribute of + /// the parent exception that this exception was acquired from. + /// In the case of an array, it should include the zero-based array index as + /// well. + final String? source; + + /// An optional numeric value providing an ID for the exception relative to + /// this specific event. + /// + /// The SDK should assign simple incrementing integers to each exception in + /// the tree, starting with 0 for the root of the tree. + /// In other words, when flattened into the list provided in the exception + /// values on the event, the last exception in the list should have ID 0, + /// the previous one should have ID 1, the next previous should have ID 2, etc. + final int? exceptionId; + + /// An optional numeric value pointing at the [exceptionId] that is the parent + /// of this exception. + /// + /// The SDK should assign this to all exceptions except the root exception + /// (the last to be listed in the exception values). + final int? parentId; + Mechanism({ required this.type, this.description, @@ -52,6 +84,10 @@ class Mechanism { this.synthetic, Map? meta, Map? data, + this.isExceptionGroup, + this.source, + this.exceptionId, + this.parentId, }) : _meta = meta != null ? Map.from(meta) : null, _data = data != null ? Map.from(data) : null; @@ -63,6 +99,10 @@ class Mechanism { Map? meta, Map? data, bool? synthetic, + bool? isExceptionGroup, + String? source, + int? exceptionId, + int? parentId, }) => Mechanism( type: type ?? this.type, @@ -72,6 +112,10 @@ class Mechanism { meta: meta ?? this.meta, data: data ?? this.data, synthetic: synthetic ?? this.synthetic, + isExceptionGroup: isExceptionGroup ?? this.isExceptionGroup, + source: source ?? this.source, + exceptionId: exceptionId ?? this.exceptionId, + parentId: parentId ?? this.parentId, ); /// Deserializes a [Mechanism] from JSON [Map]. @@ -94,6 +138,10 @@ class Mechanism { meta: meta, data: data, synthetic: json['synthetic'], + isExceptionGroup: json['is_exception_group'], + source: json['source'], + exceptionId: json['exception_id'], + parentId: json['parent_id'], ); } @@ -107,6 +155,10 @@ class Mechanism { if (_meta?.isNotEmpty ?? false) 'meta': _meta, if (_data?.isNotEmpty ?? false) 'data': _data, if (synthetic != null) 'synthetic': synthetic, + if (isExceptionGroup != null) 'is_exception_group': isExceptionGroup, + if (source != null) 'source': source, + if (exceptionId != null) 'exception_id': exceptionId, + if (parentId != null) 'parent_id': parentId, }; } } diff --git a/dart/lib/src/protocol/sentry_request.dart b/dart/lib/src/protocol/sentry_request.dart index 9689c8a974..b5ee7d003c 100644 --- a/dart/lib/src/protocol/sentry_request.dart +++ b/dart/lib/src/protocol/sentry_request.dart @@ -1,6 +1,6 @@ import 'package:meta/meta.dart'; -import '../utils/iterable_extension.dart'; +import '../utils/iterable_utils.dart'; import '../utils/http_sanitizer.dart'; /// The Request interface contains information on a HTTP request related to the event. @@ -85,9 +85,10 @@ class SentryRequest { _headers = headers != null ? Map.from(headers) : null, // Look for a 'Set-Cookie' header (case insensitive) if not given. cookies = cookies ?? - headers?.entries - .firstWhereOrNull((e) => e.key.toLowerCase() == 'cookie') - ?.value, + IterableUtils.firstWhereOrNull( + headers?.entries, + (MapEntry e) => e.key.toLowerCase() == 'cookie', + )?.value, _env = env != null ? Map.from(env) : null, _other = other != null ? Map.from(other) : null; diff --git a/dart/lib/src/protocol/sentry_response.dart b/dart/lib/src/protocol/sentry_response.dart index 91faaa37eb..6008ea8730 100644 --- a/dart/lib/src/protocol/sentry_response.dart +++ b/dart/lib/src/protocol/sentry_response.dart @@ -1,6 +1,6 @@ import 'package:meta/meta.dart'; import 'contexts.dart'; -import '../utils/iterable_extension.dart'; +import '../utils/iterable_utils.dart'; /// The response interface contains information on a HTTP request related to the event. @immutable @@ -53,9 +53,11 @@ class SentryResponse { _headers = headers != null ? Map.from(headers) : null, // Look for a 'Set-Cookie' header (case insensitive) if not given. cookies = cookies ?? - headers?.entries - .firstWhereOrNull((e) => e.key.toLowerCase() == 'set-cookie') - ?.value; + IterableUtils.firstWhereOrNull( + headers?.entries, + (MapEntry e) => + e.key.toLowerCase() == 'set-cookie', + )?.value; /// Deserializes a [SentryResponse] from JSON [Map]. factory SentryResponse.fromJson(Map json) { diff --git a/dart/lib/src/run_zoned_guarded_integration.dart b/dart/lib/src/run_zoned_guarded_integration.dart index 05ef5be2b0..20f0857e3b 100644 --- a/dart/lib/src/run_zoned_guarded_integration.dart +++ b/dart/lib/src/run_zoned_guarded_integration.dart @@ -44,8 +44,8 @@ class RunZonedGuardedIntegration extends Integration { stackTrace: stackTrace, ); - // runZonedGuarded doesn't crash the App. - final mechanism = Mechanism(type: 'runZonedGuarded', handled: true); + // runZonedGuarded doesn't crash the app, but is not handled by the user. + final mechanism = Mechanism(type: 'runZonedGuarded', handled: false); final throwableMechanism = ThrowableMechanism(mechanism, exception); final event = SentryEvent( diff --git a/dart/lib/src/scope.dart b/dart/lib/src/scope.dart index 4f36895131..3fef9a92a2 100644 --- a/dart/lib/src/scope.dart +++ b/dart/lib/src/scope.dart @@ -150,7 +150,7 @@ class Scope { Scope(this._options); - Breadcrumb? _addBreadCrumbSync(Breadcrumb breadcrumb, {Hint? hint}) { + Breadcrumb? _addBreadCrumbSync(Breadcrumb breadcrumb, Hint hint) { // bail out if maxBreadcrumbs is zero if (_options.maxBreadcrumbs == 0) { return null; @@ -162,7 +162,7 @@ class Scope { try { processedBreadcrumb = _options.beforeBreadcrumb!( processedBreadcrumb, - hint: hint, + hint, ); if (processedBreadcrumb == null) { _options.logger( @@ -196,7 +196,7 @@ class Scope { /// Adds a breadcrumb to the breadcrumbs queue Future addBreadcrumb(Breadcrumb breadcrumb, {Hint? hint}) async { - final addedBreadcrumb = _addBreadCrumbSync(breadcrumb, hint: hint); + final addedBreadcrumb = _addBreadCrumbSync(breadcrumb, hint ?? Hint()); if (addedBreadcrumb != null) { await _callScopeObservers((scopeObserver) async => await scopeObserver.addBreadcrumb(addedBreadcrumb)); @@ -282,9 +282,9 @@ class Scope { } Future applyToEvent( - SentryEvent event, { - Hint? hint, - }) async { + SentryEvent event, + Hint hint, + ) async { event = event.copyWith( transaction: event.transaction ?? transaction, user: _mergeUsers(user, event.user), @@ -332,7 +332,7 @@ class Scope { SentryEvent? processedEvent = event; for (final processor in _eventProcessors) { try { - final e = processor.apply(processedEvent!, hint: hint); + final e = processor.apply(processedEvent!, hint); if (e is Future) { processedEvent = await e; } else { @@ -442,7 +442,7 @@ class Scope { } for (final breadcrumb in List.from(_breadcrumbs)) { - clone._addBreadCrumbSync(breadcrumb); + clone._addBreadCrumbSync(breadcrumb, Hint()); } for (final eventProcessor in List.from(_eventProcessors)) { diff --git a/dart/lib/src/sentry_client.dart b/dart/lib/src/sentry_client.dart index 47c6fc0d8b..59610993ad 100644 --- a/dart/lib/src/sentry_client.dart +++ b/dart/lib/src/sentry_client.dart @@ -96,7 +96,7 @@ class SentryClient { hint ??= Hint(); if (scope != null) { - preparedEvent = await scope.applyToEvent(preparedEvent, hint: hint); + preparedEvent = await scope.applyToEvent(preparedEvent, hint); } else { _options.logger( SentryLevel.debug, 'No scope to apply on event was provided'); @@ -109,8 +109,8 @@ class SentryClient { preparedEvent = await _runEventProcessors( preparedEvent, + hint, eventProcessors: _options.eventProcessors, - hint: hint, ); // dropped by event processors @@ -120,7 +120,7 @@ class SentryClient { preparedEvent = await _runBeforeSend( preparedEvent, - hint: hint, + hint, ); // dropped by beforeSend @@ -128,8 +128,6 @@ class SentryClient { return _sentryId; } - preparedEvent = _eventWithoutBreadcrumbsIfNeeded(preparedEvent); - var attachments = List.from(scope?.attachments ?? []); attachments.addAll(hint.attachments); var screenshot = hint.screenshot; @@ -177,7 +175,7 @@ class SentryClient { platform: event.platform ?? sdkPlatform(_options.platformChecker.isWeb), ); - event = _applyDefaultPii(event); + event = _createUserOrSetDefaultIpAddress(event); if (event is SentryTransaction) { return event; @@ -257,20 +255,13 @@ class SentryClient { return event; } - /// This modifies the users IP address according - /// to [SentryOptions.sendDefaultPii]. - SentryEvent _applyDefaultPii(SentryEvent event) { - if (!_options.sendDefaultPii) { - return event; - } + SentryEvent _createUserOrSetDefaultIpAddress(SentryEvent event) { var user = event.user; if (user == null) { - user = SentryUser(ipAddress: _defaultIpAddress); - return event.copyWith(user: user); + return event.copyWith(user: SentryUser(ipAddress: _defaultIpAddress)); } else if (event.user?.ipAddress == null) { return event.copyWith(user: user.copyWith(ipAddress: _defaultIpAddress)); } - return event; } @@ -321,9 +312,11 @@ class SentryClient { SentryTransaction? preparedTransaction = _prepareEvent(transaction) as SentryTransaction; + final hint = Hint(); + if (scope != null) { - preparedTransaction = - await scope.applyToEvent(preparedTransaction) as SentryTransaction?; + preparedTransaction = await scope.applyToEvent(preparedTransaction, hint) + as SentryTransaction?; } else { _options.logger( SentryLevel.debug, 'No scope to apply on transaction was provided'); @@ -336,6 +329,7 @@ class SentryClient { preparedTransaction = await _runEventProcessors( preparedTransaction, + hint, eventProcessors: _options.eventProcessors, ) as SentryTransaction?; @@ -345,15 +339,13 @@ class SentryClient { } preparedTransaction = - await _runBeforeSend(preparedTransaction) as SentryTransaction?; + await _runBeforeSend(preparedTransaction, hint) as SentryTransaction?; // dropped by beforeSendTransaction if (preparedTransaction == null) { return _sentryId; } - preparedTransaction = _eventWithoutBreadcrumbsIfNeeded(preparedTransaction); - final attachments = scope?.attachments .where((element) => element.addToTransactions) .toList(); @@ -407,9 +399,9 @@ class SentryClient { } Future _runBeforeSend( - SentryEvent event, { - Hint? hint, - }) async { + SentryEvent event, + Hint hint, + ) async { SentryEvent? eventOrTransaction = event; final beforeSend = _options.beforeSend; @@ -426,7 +418,7 @@ class SentryClient { eventOrTransaction = e; } } else if (beforeSend != null) { - final e = beforeSend(event, hint: hint); + final e = beforeSend(event, hint); if (e is Future) { eventOrTransaction = await e; } else { @@ -457,14 +449,14 @@ class SentryClient { } Future _runEventProcessors( - SentryEvent event, { - Hint? hint, + SentryEvent event, + Hint hint, { required List eventProcessors, }) async { SentryEvent? processedEvent = event; for (final processor in eventProcessors) { try { - final e = processor.apply(processedEvent!, hint: hint); + final e = processor.apply(processedEvent!, hint); if (e is Future) { processedEvent = await e; } else { @@ -507,40 +499,6 @@ class SentryClient { _options.recorder.recordLostEvent(reason, category); } - T _eventWithoutBreadcrumbsIfNeeded(T event) { - if (_shouldRemoveBreadcrumbs(event)) { - return event.copyWith(breadcrumbs: []) as T; - } else { - return event; - } - } - - /// We do this to avoid duplicate breadcrumbs on Android as sentry-android applies the breadcrumbs - /// from the native scope onto every envelope sent through it. This scope will contain the breadcrumbs - /// sent through the scope sync feature. This causes duplicate breadcrumbs. - /// We then remove the breadcrumbs in all cases but if it is handled == false, - /// this is a signal that the app would crash and android would lose the breadcrumbs by the time the app is restarted to read - /// the envelope. - bool _shouldRemoveBreadcrumbs(SentryEvent event) { - if (_options.platformChecker.isWeb) { - return false; - } - - final isAndroid = _options.platformChecker.platform.isAndroid; - final enableScopeSync = _options.enableScopeSync; - - if (!isAndroid || !enableScopeSync) { - return false; - } - - final mechanisms = - (event.exceptions ?? []).map((e) => e.mechanism).whereType(); - final hasNoMechanism = mechanisms.isEmpty; - final hasOnlyHandledMechanism = - mechanisms.every((e) => (e.handled ?? true)); - return hasNoMechanism || hasOnlyHandledMechanism; - } - Future _attachClientReportsAndSend(SentryEnvelope envelope) { final clientReport = _options.recorder.flush(); envelope.addClientReport(clientReport); diff --git a/dart/lib/src/sentry_isolate.dart b/dart/lib/src/sentry_isolate.dart index 0af2978e24..9998544d5b 100644 --- a/dart/lib/src/sentry_isolate.dart +++ b/dart/lib/src/sentry_isolate.dart @@ -69,9 +69,10 @@ class SentryIsolate { stackTrace == null ? null : StackTrace.fromString(stackTrace), ); - // Isolate errors don't crash the App. - final mechanism = Mechanism(type: 'isolateError', handled: true); + // Isolate errors don't crash the app, but is not handled by the user. + final mechanism = Mechanism(type: 'isolateError', handled: false); final throwableMechanism = ThrowableMechanism(mechanism, throwable); + final event = SentryEvent( throwable: throwableMechanism, level: hub.options.markAutomaticallyCollectedErrorsAsFatal diff --git a/dart/lib/src/sentry_options.dart b/dart/lib/src/sentry_options.dart index eea642ae48..956f81c056 100644 --- a/dart/lib/src/sentry_options.dart +++ b/dart/lib/src/sentry_options.dart @@ -529,9 +529,9 @@ class SentryOptions { /// This function is called with an SDK specific event object and can return a modified event /// object or nothing to skip reporting the event typedef BeforeSendCallback = FutureOr Function( - SentryEvent event, { - Hint? hint, -}); + SentryEvent event, + Hint hint, +); /// This function is called with an SDK specific transaction object and can return a modified transaction /// object or nothing to skip reporting the transaction @@ -542,9 +542,9 @@ typedef BeforeSendTransactionCallback = FutureOr Function( /// This function is called with an SDK specific breadcrumb object before the breadcrumb is added /// to the scope. When nothing is returned from the function, the breadcrumb is dropped typedef BeforeBreadcrumbCallback = Breadcrumb? Function( - Breadcrumb? breadcrumb, { - Hint? hint, -}); + Breadcrumb? breadcrumb, + Hint hint, +); /// This function is called right before a metric is about to be emitted. /// Can return true to emit the metric, or false to drop it. diff --git a/dart/lib/src/sentry_tracer.dart b/dart/lib/src/sentry_tracer.dart index d9ea75d256..2326db0716 100644 --- a/dart/lib/src/sentry_tracer.dart +++ b/dart/lib/src/sentry_tracer.dart @@ -100,15 +100,6 @@ class SentryTracer extends ISentrySpan { _children.removeWhere( (span) => !_hasSpanSuitableTimestamps(span, commonEndTimestamp)); - // finish unfinished spans otherwise transaction gets dropped - final spansToBeFinished = _children.where((span) => !span.finished); - for (final span in spansToBeFinished) { - await span.finish( - status: SpanStatus.deadlineExceeded(), - endTimestamp: commonEndTimestamp, - ); - } - var _rootEndTimestamp = commonEndTimestamp; // Trim the end timestamp of the transaction to the very last timestamp of child spans diff --git a/dart/lib/src/transport/data_category.dart b/dart/lib/src/transport/data_category.dart index f21da18ed7..ecdb1c9500 100644 --- a/dart/lib/src/transport/data_category.dart +++ b/dart/lib/src/transport/data_category.dart @@ -10,50 +10,3 @@ enum DataCategory { metricBucket, unknown } - -extension DataCategoryExtension on DataCategory { - static DataCategory fromStringValue(String stringValue) { - switch (stringValue) { - case '__all__': - return DataCategory.all; - case 'default': - return DataCategory.dataCategoryDefault; - case 'error': - return DataCategory.error; - case 'session': - return DataCategory.session; - case 'transaction': - return DataCategory.transaction; - case 'attachment': - return DataCategory.attachment; - case 'security': - return DataCategory.security; - case 'metric_bucket': - return DataCategory.metricBucket; - } - return DataCategory.unknown; - } - - String toStringValue() { - switch (this) { - case DataCategory.all: - return '__all__'; - case DataCategory.dataCategoryDefault: - return 'default'; - case DataCategory.error: - return 'error'; - case DataCategory.session: - return 'session'; - case DataCategory.transaction: - return 'transaction'; - case DataCategory.attachment: - return 'attachment'; - case DataCategory.security: - return 'security'; - case DataCategory.metricBucket: - return 'metric_bucket'; - case DataCategory.unknown: - return 'unknown'; - } - } -} diff --git a/dart/lib/src/transport/rate_limit_parser.dart b/dart/lib/src/transport/rate_limit_parser.dart index 03391e0210..1cf1a7e3e1 100644 --- a/dart/lib/src/transport/rate_limit_parser.dart +++ b/dart/lib/src/transport/rate_limit_parser.dart @@ -30,8 +30,8 @@ class RateLimitParser { if (allCategories.isNotEmpty) { final categoryValues = allCategories.split(';'); for (final categoryValue in categoryValues) { - final category = DataCategoryExtension.fromStringValue(categoryValue); - // Metric buckets rate limit can have namespaces + final category = _DataCategoryExtension._fromStringValue( + categoryValue); // Metric buckets rate limit can have namespaces if (category == DataCategory.metricBucket) { final namespaces = durationAndCategories.length > 4 ? durationAndCategories[4] @@ -67,3 +67,27 @@ class RateLimitParser { } } } + +extension _DataCategoryExtension on DataCategory { + static DataCategory _fromStringValue(String stringValue) { + switch (stringValue) { + case '__all__': + return DataCategory.all; + case 'default': + return DataCategory.dataCategoryDefault; + case 'error': + return DataCategory.error; + case 'session': + return DataCategory.session; + case 'transaction': + return DataCategory.transaction; + case 'attachment': + return DataCategory.attachment; + case 'security': + return DataCategory.security; + case 'metric_bucket': + return DataCategory.metricBucket; + } + return DataCategory.unknown; + } +} diff --git a/dart/lib/src/utils/http_sanitizer.dart b/dart/lib/src/utils/http_sanitizer.dart index c131cc0c4e..2e5de505a9 100644 --- a/dart/lib/src/utils/http_sanitizer.dart +++ b/dart/lib/src/utils/http_sanitizer.dart @@ -60,7 +60,7 @@ class HttpSanitizer { } } -extension UriPath on Uri { +extension _UriPath on Uri { String _urlWithRedactedAuth() { var buffer = ''; if (scheme.isNotEmpty) { @@ -78,6 +78,7 @@ extension UriPath on Uri { } } +@internal extension SanitizedSentryRequest on SentryRequest { SentryRequest sanitized() { final urlDetails = HttpSanitizer.sanitizeUrl(url) ?? UrlDetails(); diff --git a/dart/lib/src/utils/isolate_utils.dart b/dart/lib/src/utils/isolate_utils.dart index ce523b0d63..3e9c4b20bc 100644 --- a/dart/lib/src/utils/isolate_utils.dart +++ b/dart/lib/src/utils/isolate_utils.dart @@ -1,4 +1,7 @@ +import 'package:meta/meta.dart'; + import '_io_get_isolate_name.dart' if (dart.library.html) '_web_get_isolate_name.dart' as isolate_getter; +@internal String? getIsolateName() => isolate_getter.getIsolateName(); diff --git a/dart/lib/src/utils/iterable_extension.dart b/dart/lib/src/utils/iterable_extension.dart deleted file mode 100644 index 34c2c60943..0000000000 --- a/dart/lib/src/utils/iterable_extension.dart +++ /dev/null @@ -1,8 +0,0 @@ -extension IterableExtension on Iterable { - T? firstWhereOrNull(bool Function(T item) predicate) { - for (var item in this) { - if (predicate(item)) return item; - } - return null; - } -} diff --git a/dart/lib/src/utils/iterable_utils.dart b/dart/lib/src/utils/iterable_utils.dart new file mode 100644 index 0000000000..c2fb5e5c69 --- /dev/null +++ b/dart/lib/src/utils/iterable_utils.dart @@ -0,0 +1,17 @@ +import 'package:meta/meta.dart'; + +@internal +class IterableUtils { + static T? firstWhereOrNull( + Iterable? iterable, + bool Function(T item) test, + ) { + if (iterable == null) { + return null; + } + for (var item in iterable) { + if (test(item)) return item; + } + return null; + } +} diff --git a/dart/lib/src/version.dart b/dart/lib/src/version.dart index 7e4666bc06..a62754b2dc 100644 --- a/dart/lib/src/version.dart +++ b/dart/lib/src/version.dart @@ -9,7 +9,7 @@ library version; /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; String sdkName(bool isWeb) => isWeb ? _browserSdkName : _ioSdkName; diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml index 4294d86144..bc2ef30452 100644 --- a/dart/pubspec.yaml +++ b/dart/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry -version: 7.20.0 +version: 8.0.0 description: > A crash reporting library for Dart that sends crash reports to Sentry.io. This library supports Dart VM and Web. For Flutter consider sentry_flutter instead. diff --git a/dart/test/event_processor/deduplication_event_processor_test.dart b/dart/test/event_processor/deduplication_event_processor_test.dart index 54592351bb..3e17fe4065 100644 --- a/dart/test/event_processor/deduplication_event_processor_test.dart +++ b/dart/test/event_processor/deduplication_event_processor_test.dart @@ -15,16 +15,16 @@ void main() { final sut = fixture.getSut(true); var ogEvent = _createEvent('foo'); - expect(sut.apply(ogEvent), isNotNull); - expect(sut.apply(ogEvent), isNull); + expect(sut.apply(ogEvent, Hint()), isNotNull); + expect(sut.apply(ogEvent, Hint()), isNull); }); test('does not deduplicate if disabled', () { final sut = fixture.getSut(false); var ogEvent = _createEvent('foo'); - expect(sut.apply(ogEvent), isNotNull); - expect(sut.apply(ogEvent), isNotNull); + expect(sut.apply(ogEvent, Hint()), isNotNull); + expect(sut.apply(ogEvent, Hint()), isNotNull); }); test('does not deduplicate if different events', () { @@ -32,16 +32,16 @@ void main() { var fooEvent = _createEvent('foo'); var barEvent = _createEvent('bar'); - expect(sut.apply(fooEvent), isNotNull); - expect(sut.apply(barEvent), isNotNull); + expect(sut.apply(fooEvent, Hint()), isNotNull); + expect(sut.apply(barEvent, Hint()), isNotNull); }); test('does not deduplicate transaction', () { final sut = fixture.getSut(true); final transaction = _createTransaction(fixture.hub); - expect(sut.apply(transaction), isNotNull); - expect(sut.apply(transaction), isNotNull); + expect(sut.apply(transaction, Hint()), isNotNull); + expect(sut.apply(transaction, Hint()), isNotNull); }); test('exceptions to keep for deduplication', () { @@ -51,10 +51,10 @@ void main() { var barEvent = _createEvent('bar'); var fooBarEvent = _createEvent('foo bar'); - expect(sut.apply(fooEvent), isNotNull); - expect(sut.apply(barEvent), isNotNull); - expect(sut.apply(fooBarEvent), isNotNull); - expect(sut.apply(fooEvent), isNotNull); + expect(sut.apply(fooEvent, Hint()), isNotNull); + expect(sut.apply(barEvent, Hint()), isNotNull); + expect(sut.apply(fooBarEvent, Hint()), isNotNull); + expect(sut.apply(fooEvent, Hint()), isNotNull); }); test('integration test', () async { diff --git a/dart/test/event_processor/enricher/io_enricher_test.dart b/dart/test/event_processor/enricher/io_enricher_test.dart index 1704960edc..72080cba3f 100644 --- a/dart/test/event_processor/enricher/io_enricher_test.dart +++ b/dart/test/event_processor/enricher/io_enricher_test.dart @@ -17,7 +17,7 @@ void main() { test('adds dart runtime', () { final enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.runtimes, isNotEmpty); final dartRuntime = event?.contexts.runtimes @@ -31,7 +31,7 @@ void main() { var event = SentryEvent(contexts: Contexts(runtimes: [runtime])); final enricher = fixture.getSut(); - event = enricher.apply(event)!; + event = enricher.apply(event, Hint())!; expect(event.contexts.runtimes.contains(runtime), true); // second runtime is Dart runtime @@ -42,7 +42,7 @@ void main() { 'does not add device, os and culture if native integration is available', () { final enricher = fixture.getSut(hasNativeIntegration: true); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device, isNull); expect(event?.contexts.operatingSystem, isNull); @@ -52,7 +52,7 @@ void main() { test('adds device, os and culture if no native integration is available', () { final enricher = fixture.getSut(hasNativeIntegration: false); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device, isNotNull); expect(event?.contexts.operatingSystem, isNotNull); @@ -61,14 +61,14 @@ void main() { test('device has name', () { final enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device?.name, isNotNull); }); test('culture has locale and timezone', () { final enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.culture?.locale, isNotNull); expect(event?.contexts.culture?.timezone, isNotNull); @@ -76,7 +76,7 @@ void main() { test('os has name and version', () { final enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.operatingSystem?.name, isNotNull); expect(event?.contexts.operatingSystem?.version, isNotNull); @@ -84,7 +84,7 @@ void main() { test('adds Dart context with PII', () { final enricher = fixture.getSut(includePii: true); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); final dartContext = event?.contexts['dart_context']; expect(dartContext, isNotNull); @@ -97,7 +97,7 @@ void main() { test('adds Dart context without PII', () { final enricher = fixture.getSut(includePii: false); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); final dartContext = event?.contexts['dart_context']; expect(dartContext, isNotNull); @@ -131,7 +131,7 @@ void main() { hasNativeIntegration: false, ); - final event = enricher.apply(fakeEvent); + final event = enricher.apply(fakeEvent, Hint()); // contexts.device expect( diff --git a/dart/test/event_processor/enricher/web_enricher_test.dart b/dart/test/event_processor/enricher/web_enricher_test.dart index 60076e506a..e5d5b2efec 100644 --- a/dart/test/event_processor/enricher/web_enricher_test.dart +++ b/dart/test/event_processor/enricher/web_enricher_test.dart @@ -20,21 +20,21 @@ void main() { test('add path as transaction if transaction is null', () { var enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.transaction, isNotNull); }); test("don't overwrite transaction", () { var enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent(transaction: 'foobar')); + final event = enricher.apply(SentryEvent(transaction: 'foobar'), Hint()); expect(event?.transaction, 'foobar'); }); test('add request with user-agent header', () { var enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.request?.headers['User-Agent'], isNotNull); expect(event?.request?.url, isNotNull); @@ -50,7 +50,7 @@ void main() { ), ); var enricher = fixture.getSut(); - event = enricher.apply(event)!; + event = enricher.apply(event, Hint())!; expect(event.request?.headers['User-Agent'], isNotNull); expect(event.request?.headers['foo'], 'bar'); @@ -68,7 +68,7 @@ void main() { ), ); var enricher = fixture.getSut(); - event = enricher.apply(event)!; + event = enricher.apply(event, Hint())!; expect(event.request?.headers['Authorization'], isNull); expect(event.request?.headers['authorization'], isNull); @@ -84,7 +84,7 @@ void main() { ), ); var enricher = fixture.getSut(); - event = enricher.apply(event)!; + event = enricher.apply(event, Hint())!; expect(event.request?.headers['User-Agent'], 'best browser agent'); expect(event.request?.url, 'foo.bar'); @@ -92,14 +92,14 @@ void main() { test('adds device and os', () { var enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device, isNotNull); }); test('adds Dart context', () { final enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); final dartContext = event?.contexts['dart_context']; expect(dartContext, isNotNull); @@ -108,14 +108,14 @@ void main() { test('device has screendensity', () { var enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device?.screenDensity, isNotNull); }); test('culture has timezone', () { var enricher = fixture.getSut(); - final event = enricher.apply(SentryEvent()); + final event = enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.culture?.timezone, isNotNull); }); @@ -142,7 +142,7 @@ void main() { final enricher = fixture.getSut(); - final event = enricher.apply(fakeEvent); + final event = enricher.apply(fakeEvent, Hint()); // contexts.device expect( diff --git a/dart/test/event_processor/exception/io_exception_event_processor_test.dart b/dart/test/event_processor/exception/io_exception_event_processor_test.dart index 14d2720df2..5d4d771a08 100644 --- a/dart/test/event_processor/exception/io_exception_event_processor_test.dart +++ b/dart/test/event_processor/exception/io_exception_event_processor_test.dart @@ -23,6 +23,7 @@ void main() { uri: Uri.parse('https://example.org/foo/bar?foo=bar'), ), ), + Hint(), ); expect(event?.request, isNotNull); @@ -36,6 +37,7 @@ void main() { SentryEvent( throwable: HttpException(''), ), + Hint(), ); expect(event?.request, isNull); @@ -55,6 +57,7 @@ void main() { ), ), ), + Hint(), ); expect(event?.request, isNotNull); @@ -81,6 +84,7 @@ void main() { OSError('Oh no :(', 42), ), ), + Hint(), ); // Due to the test setup, there's no SentryException for the FileSystemException. diff --git a/dart/test/http_client/failed_request_client_test.dart b/dart/test/http_client/failed_request_client_test.dart index 9c450f8bd2..2ac9a74c8e 100644 --- a/dart/test/http_client/failed_request_client_test.dart +++ b/dart/test/http_client/failed_request_client_test.dart @@ -332,7 +332,7 @@ void main() { final sut = fixture.getSut(client: client); Hint? eventHint; - fixture.options.addEventProcessor(FunctionEventProcessor((event, {hint}) { + fixture.options.addEventProcessor(FunctionEventProcessor((event, hint) { eventHint = hint; return event; })); diff --git a/dart/test/mocks.dart b/dart/test/mocks.dart index 1c79599a6b..7c960c8a07 100644 --- a/dart/test/mocks.dart +++ b/dart/test/mocks.dart @@ -132,7 +132,7 @@ final Map> fakeMetrics = { /// Always returns null and thus drops all events class DropAllEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { return null; } } @@ -143,13 +143,13 @@ class FunctionEventProcessor implements EventProcessor { final EventProcessorFunction applyFunction; @override - SentryEvent? apply(SentryEvent event, {hint}) { - return applyFunction(event, hint: hint); + SentryEvent? apply(SentryEvent event, Hint hint) { + return applyFunction(event, hint); } } -typedef EventProcessorFunction = SentryEvent? Function(SentryEvent event, - {Hint? hint}); +typedef EventProcessorFunction = SentryEvent? Function( + SentryEvent event, Hint hint); var fakeEnvelope = SentryEnvelope.fromEvent( fakeEvent, diff --git a/dart/test/protocol/mechanism_test.dart b/dart/test/protocol/mechanism_test.dart index 4b484d2ca3..857a0529a9 100644 --- a/dart/test/protocol/mechanism_test.dart +++ b/dart/test/protocol/mechanism_test.dart @@ -11,6 +11,10 @@ void main() { synthetic: true, meta: {'key': 'value'}, data: {'keyb': 'valueb'}, + isExceptionGroup: false, + exceptionId: 0, + parentId: 0, + source: 'source', ); final mechanismJson = { @@ -21,6 +25,10 @@ void main() { 'meta': {'key': 'value'}, 'data': {'keyb': 'valueb'}, 'synthetic': true, + 'is_exception_group': false, + 'source': 'source', + 'exception_id': 0, + 'parent_id': 0, }; group('json', () { @@ -51,6 +59,7 @@ void main() { expect(data.toJson(), copy.toJson()); }); + test('copyWith takes new values', () { final data = mechanism; @@ -62,6 +71,10 @@ void main() { synthetic: false, meta: {'key1': 'value1'}, data: {'keyb1': 'valueb1'}, + exceptionId: 1, + parentId: 1, + isExceptionGroup: false, + source: 'foo', ); expect('type1', copy.type); @@ -71,6 +84,10 @@ void main() { expect(false, copy.synthetic); expect({'key1': 'value1'}, copy.meta); expect({'keyb1': 'valueb1'}, copy.data); + expect(1, copy.exceptionId); + expect(1, copy.parentId); + expect(false, copy.isExceptionGroup); + expect('foo', copy.source); }); }); } diff --git a/dart/test/scope_test.dart b/dart/test/scope_test.dart index 6f21e5e63c..66cc543b6b 100644 --- a/dart/test/scope_test.dart +++ b/dart/test/scope_test.dart @@ -98,6 +98,26 @@ void main() { expect(sut.breadcrumbs.last, breadcrumb); }); + test('beforeBreadcrumb called with user provided hint', () { + Hint? actual; + BeforeBreadcrumbCallback bb = (_, hint) { + actual = hint; + return null; + }; + final sut = fixture.getSut( + beforeBreadcrumbCallback: bb, + ); + + final breadcrumb = Breadcrumb( + message: 'test log', + timestamp: DateTime.utc(2019), + ); + final hint = Hint.withMap({'user-name': 'joe dirt'}); + sut.addBreadcrumb(breadcrumb, hint: hint); + + expect(actual?.get('user-name'), 'joe dirt'); + }); + test('Executes and drops $Breadcrumb', () { final sut = fixture.getSut( beforeBreadcrumbCallback: fixture.beforeBreadcrumbCallback, @@ -412,7 +432,7 @@ void main() { await scope.setContexts('theme', 'material'); await scope.setUser(scopeUser); - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.user, scopeUser); expect(updatedEvent?.transaction, '/example/app'); @@ -433,7 +453,7 @@ void main() { final scope = Scope(SentryOptions(dsn: fakeDsn)) ..span = fixture.sentryTracer; - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.contexts['trace'] is SentryTraceContext, true); }); @@ -456,7 +476,7 @@ void main() { await scope.addBreadcrumb(breadcrumb); await scope.setUser(scopeUser); - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.user, isNotNull); expect(updatedEvent?.user?.id, eventUser.id); @@ -504,7 +524,7 @@ void main() { SentryOperatingSystem(name: 'context-os'), ); - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.contexts[SentryDevice.type].name, 'event-device'); expect(updatedEvent?.contexts[SentryApp.type].name, 'event-app'); @@ -534,7 +554,7 @@ void main() { await scope.setContexts('location', {'city': 'London'}); await scope.setContexts('items', [1, 2, 3]); - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.contexts[SentryDevice.type].name, 'context-device'); expect(updatedEvent?.contexts[SentryApp.type].name, 'context-app'); @@ -559,7 +579,7 @@ void main() { final scope = Scope(SentryOptions(dsn: fakeDsn)) ..level = SentryLevel.error; - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.level, SentryLevel.error); }); @@ -569,7 +589,7 @@ void main() { final scope = Scope(SentryOptions(dsn: fakeDsn)) ..span = fixture.sentryTracer; - final updatedEvent = await scope.applyToEvent(event); + final updatedEvent = await scope.applyToEvent(event, Hint()); expect(updatedEvent?.transaction, 'name'); }); @@ -581,7 +601,7 @@ void main() { sut.addEventProcessor(fixture.processor); final event = SentryEvent(); - var newEvent = await sut.applyToEvent(event); + var newEvent = await sut.applyToEvent(event, Hint()); expect(newEvent, isNull); }); @@ -590,7 +610,7 @@ void main() { var tr = SentryTransaction(fixture.sentryTracer); final scope = Scope(SentryOptions(dsn: fakeDsn))..fingerprint = ['test']; - final updatedTr = await scope.applyToEvent(tr); + final updatedTr = await scope.applyToEvent(tr, Hint()); expect(updatedTr?.fingerprint, isNull); }); @@ -599,7 +619,7 @@ void main() { var tr = SentryTransaction(fixture.sentryTracer); final scope = Scope(SentryOptions(dsn: fakeDsn))..level = SentryLevel.error; - final updatedTr = await scope.applyToEvent(tr); + final updatedTr = await scope.applyToEvent(tr, Hint()); expect(updatedTr?.level, isNull); }); @@ -608,7 +628,7 @@ void main() { var tr = SentryTransaction(fixture.sentryTracer); final scope = Scope(SentryOptions(dsn: fakeDsn))..level = SentryLevel.error; - final updatedTr = await scope.applyToEvent(tr); + final updatedTr = await scope.applyToEvent(tr, Hint()); expect(updatedTr?.contexts.trace?.sampled, isTrue); }); @@ -625,9 +645,9 @@ void main() { final sut = fixture.getSut( scopeObserver: fixture.mockScopeObserver, beforeBreadcrumbCallback: ( - Breadcrumb? breadcrumb, { - Hint? hint, - }) { + Breadcrumb? breadcrumb, + Hint hint, + ) { return breadcrumb?.copyWith(message: "modified"); }, ); @@ -698,9 +718,9 @@ void main() { final sut = fixture.getSut( beforeBreadcrumbCallback: ( - Breadcrumb? breadcrumb, { - Hint? hint, - }) { + Breadcrumb? breadcrumb, + Hint hint, + ) { throw exception; }, debug: true); @@ -722,9 +742,9 @@ void main() { final sut = fixture.getSut( beforeBreadcrumbCallback: ( - Breadcrumb? breadcrumb, { - Hint? hint, - }) { + Breadcrumb? breadcrumb, + Hint hint, + ) { if (numberOfBeforeBreadcrumbCalls > 0) { throw exception; } @@ -785,11 +805,11 @@ class Fixture { EventProcessor get processor => DropAllEventProcessor(); - Breadcrumb? beforeBreadcrumbCallback(Breadcrumb? breadcrumb, {Hint? hint}) => + Breadcrumb? beforeBreadcrumbCallback(Breadcrumb? breadcrumb, Hint hint) => null; - Breadcrumb? beforeBreadcrumbMutateCallback(Breadcrumb? breadcrumb, - {Hint? hint}) => + Breadcrumb? beforeBreadcrumbMutateCallback( + Breadcrumb? breadcrumb, Hint hint) => breadcrumb?.copyWith(message: 'new message'); void mockLogger( @@ -810,7 +830,7 @@ class AddTagsEventProcessor implements EventProcessor { AddTagsEventProcessor(this.tags); @override - SentryEvent? apply(SentryEvent event, {hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { return event..tags?.addAll(tags); } } diff --git a/dart/test/sentry_client_test.dart b/dart/test/sentry_client_test.dart index ca7718ba32..89a5620acc 100644 --- a/dart/test/sentry_client_test.dart +++ b/dart/test/sentry_client_test.dart @@ -13,6 +13,7 @@ import 'package:sentry/src/sentry_item_type.dart'; import 'package:sentry/src/sentry_stack_trace_factory.dart'; import 'package:sentry/src/sentry_tracer.dart'; import 'package:sentry/src/transport/data_category.dart'; +import 'package:sentry/src/utils/iterable_utils.dart'; import 'package:sentry/src/transport/spotlight_http_transport.dart'; import 'package:test/test.dart'; @@ -937,25 +938,14 @@ void main() { }); }); - group('SentryClient: apply default pii', () { + group('SentryClient: sets user & user ip', () { late Fixture fixture; setUp(() { fixture = Fixture(); }); - test('sendDefaultPii is disabled', () async { - final client = fixture.getSut(sendDefaultPii: false); - - await client.captureEvent(fakeEvent); - - final capturedEnvelope = fixture.transport.envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect(capturedEvent.user?.toJson(), fakeEvent.user?.toJson()); - }); - - test('sendDefaultPii is enabled and event has no user', () async { + test('event has no user', () async { final client = fixture.getSut(sendDefaultPii: true); var fakeEvent = SentryEvent(); @@ -969,8 +959,7 @@ void main() { expect(capturedEvent.user?.ipAddress, '{{auto}}'); }); - test('sendDefaultPii is enabled and event has a user with IP address', - () async { + test('event has a user with IP address', () async { final client = fixture.getSut(sendDefaultPii: true); await client.captureEvent(fakeEvent); @@ -986,8 +975,7 @@ void main() { expect(capturedEvent.user?.email, fakeEvent.user!.email); }); - test('sendDefaultPii is enabled and event has a user without IP address', - () async { + test('event has a user without IP address', () async { final client = fixture.getSut(sendDefaultPii: true); final event = fakeEvent.copyWith(user: fakeUser); @@ -1150,7 +1138,7 @@ void main() { test('thrown error is handled', () async { final exception = Exception("before send exception"); - final beforeSendCallback = (SentryEvent event, {Hint? hint}) { + final beforeSendCallback = (SentryEvent event, Hint hint) { throw exception; }; @@ -1170,7 +1158,7 @@ void main() { setUp(() { fixture = Fixture(); fixture.options.addEventProcessor(FunctionEventProcessor( - (event, {hint}) => event + (event, hint) => event ..tags!.addAll({'theme': 'material'}) // ignore: deprecated_member_use_from_same_package ..extra!['host'] = '0.0.0.1' @@ -1212,8 +1200,8 @@ void main() { var executed = false; - final client = fixture.getSut( - eventProcessor: FunctionEventProcessor((event, {hint}) { + final client = + fixture.getSut(eventProcessor: FunctionEventProcessor((event, hint) { expect(myHint, hint); executed = true; return event; @@ -1227,8 +1215,8 @@ void main() { test('should create hint when none was provided', () async { var executed = false; - final client = fixture.getSut( - eventProcessor: FunctionEventProcessor((event, {hint}) { + final client = + fixture.getSut(eventProcessor: FunctionEventProcessor((event, hint) { expect(hint, isNotNull); executed = true; return event; @@ -1264,201 +1252,6 @@ void main() { }); }); - group('Breadcrumbs', () { - late Fixture fixture; - - setUp(() { - fixture = Fixture(); - }); - - test('Clears breadcrumbs on Android for transaction', () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = - MockPlatformChecker(platform: MockPlatform.android()); - - final client = fixture.getSut(); - final transaction = SentryTransaction( - fixture.tracer, - breadcrumbs: [ - Breadcrumb(), - ], - ); - await client.captureTransaction(transaction); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedTransaction = - await transactionFromEnvelope(capturedEnvelope); - - expect((capturedTransaction['breadcrumbs'] ?? []).isEmpty, true); - }); - - test('Clears breadcrumbs on Android if mechanism.handled is true for event', - () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = - MockPlatformChecker(platform: MockPlatform.android()); - - final client = fixture.getSut(); - final event = SentryEvent(exceptions: [ - SentryException( - type: "type", - value: "value", - mechanism: Mechanism( - type: 'type', - handled: true, - ), - ) - ], breadcrumbs: [ - Breadcrumb() - ]); - await client.captureEvent(event); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect((capturedEvent.breadcrumbs ?? []).isEmpty, true); - }); - - test('Clears breadcrumbs on Android if mechanism.handled is null for event', - () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = - MockPlatformChecker(platform: MockPlatform.android()); - - final client = fixture.getSut(); - final event = SentryEvent(exceptions: [ - SentryException( - type: "type", - value: "value", - mechanism: Mechanism(type: 'type'), - ) - ], breadcrumbs: [ - Breadcrumb() - ]); - await client.captureEvent(event); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect((capturedEvent.breadcrumbs ?? []).isEmpty, true); - }); - - test('Clears breadcrumbs on Android if theres no mechanism for event', - () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = - MockPlatformChecker(platform: MockPlatform.android()); - - final client = fixture.getSut(); - final event = SentryEvent(exceptions: [ - SentryException( - type: "type", - value: "value", - ) - ], breadcrumbs: [ - Breadcrumb() - ]); - await client.captureEvent(event); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect((capturedEvent.breadcrumbs ?? []).isEmpty, true); - }); - - test( - 'Does not clear breadcrumbs on Android if mechanism.handled is false for event', - () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = - MockPlatformChecker(platform: MockPlatform.android()); - - final client = fixture.getSut(); - final event = SentryEvent(exceptions: [ - SentryException( - type: "type", - value: "value", - mechanism: Mechanism( - type: 'type', - handled: false, - ), - ) - ], breadcrumbs: [ - Breadcrumb() - ]); - await client.captureEvent(event); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect((capturedEvent.breadcrumbs ?? []).isNotEmpty, true); - }); - - test( - 'Does not clear breadcrumbs on Android if any mechanism.handled is false for event', - () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = - MockPlatformChecker(platform: MockPlatform.android()); - - final client = fixture.getSut(); - final event = SentryEvent(exceptions: [ - SentryException( - type: "type", - value: "value", - mechanism: Mechanism( - type: 'type', - handled: true, - ), - ), - SentryException( - type: "type", - value: "value", - mechanism: Mechanism( - type: 'type', - handled: false, - ), - ) - ], breadcrumbs: [ - Breadcrumb() - ]); - await client.captureEvent(event); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect((capturedEvent.breadcrumbs ?? []).isNotEmpty, true); - }); - - test('web breadcrumbs exist on web Android devices', () async { - fixture.options.enableScopeSync = true; - fixture.options.platformChecker = MockPlatformChecker( - platform: MockPlatform.android(), - isWebValue: true, - ); - - final client = fixture.getSut(); - final event = SentryEvent(exceptions: [ - SentryException( - type: "type", - value: "value", - mechanism: Mechanism( - type: 'type', - handled: true, - ), - ), - ], breadcrumbs: [ - Breadcrumb(), - ]); - await client.captureEvent(event); - - final capturedEnvelope = (fixture.transport).envelopes.first; - final capturedEvent = await eventFromEnvelope(capturedEnvelope); - - expect((capturedEvent.breadcrumbs ?? []).isNotEmpty, true); - }); - }); - group('ClientReportRecorder', () { late Fixture fixture; @@ -1538,8 +1331,10 @@ void main() { await sut.captureEvent(fakeEvent, hint: hint); final capturedEnvelope = (fixture.transport).envelopes.first; - final attachmentItem = capturedEnvelope.items.firstWhereOrNull( - (element) => element.header.type == SentryItemType.attachment); + final attachmentItem = IterableUtils.firstWhereOrNull( + capturedEnvelope.items, + (SentryEnvelopeItem e) => e.header.type == SentryItemType.attachment, + ); expect(attachmentItem?.header.attachmentType, SentryAttachment.typeAttachmentDefault); }); @@ -1754,9 +1549,9 @@ Future> transactionFromEnvelope( } SentryEvent? beforeSendCallbackDropEvent( - SentryEvent event, { - Hint? hint, -}) => + SentryEvent event, + Hint hint, +) => null; SentryTransaction? beforeSendTransactionCallbackDropEvent( @@ -1765,9 +1560,9 @@ SentryTransaction? beforeSendTransactionCallbackDropEvent( null; Future asyncBeforeSendCallbackDropEvent( - SentryEvent event, { - Hint? hint, -}) async { + SentryEvent event, + Hint hint, +) async { await Future.delayed(Duration(milliseconds: 200)); return null; } @@ -1778,7 +1573,7 @@ Future asyncBeforeSendTransactionCallbackDropEvent( return null; } -SentryEvent? beforeSendCallback(SentryEvent event, {Hint? hint}) { +SentryEvent? beforeSendCallback(SentryEvent event, Hint hint) { return event ..tags!.addAll({'theme': 'material'}) // ignore: deprecated_member_use_from_same_package @@ -1856,8 +1651,7 @@ class Fixture { return client; } - Future droppingBeforeSend(SentryEvent event, - {Hint? hint}) async { + Future droppingBeforeSend(SentryEvent event, Hint hint) async { return null; } diff --git a/dart/test/sentry_tracer_test.dart b/dart/test/sentry_tracer_test.dart index 77914e66d3..7ba5e80fac 100644 --- a/dart/test/sentry_tracer_test.dart +++ b/dart/test/sentry_tracer_test.dart @@ -68,24 +68,7 @@ void main() { expect(sut.endTimestamp, endTimestamp); }); - test( - 'tracer finish sets given end timestamp to all children while finishing them', - () async { - final sut = fixture.getSut(); - - final childA = sut.startChild('operation-a', description: 'description'); - final childB = sut.startChild('operation-b', description: 'description'); - final endTimestamp = getUtcDateTime(); - - await sut.finish(endTimestamp: endTimestamp); - await childA.finish(); - await childB.finish(); - - expect(childA.endTimestamp, endTimestamp); - expect(childB.endTimestamp, endTimestamp); - }); - - test('tracer finishes unfinished spans', () async { + test('tracer does not finish unfinished spans', () async { final sut = fixture.getSut(); sut.startChild('child'); @@ -94,7 +77,8 @@ void main() { final tr = fixture.hub.captureTransactionCalls.first; final child = tr.transaction.spans.first; - expect(child.status.toString(), 'deadline_exceeded'); + expect(child.status, isNull); + expect(child.endTimestamp, isNull); }); test('tracer sets data to extra', () async { diff --git a/dart/test/utils/http_sanitizer_test.dart b/dart/test/utils/http_sanitizer_test.dart index f9967c2778..2a4e0a58be 100644 --- a/dart/test/utils/http_sanitizer_test.dart +++ b/dart/test/utils/http_sanitizer_test.dart @@ -182,7 +182,7 @@ void main() { }); } -extension StringExtension on String { +extension _StringExtension on String { String _capitalize() { return "${this[0].toUpperCase()}${substring(1).toLowerCase()}"; } diff --git a/dio/README.md b/dio/README.md index 72c1cbeaa8..a8cf767237 100644 --- a/dio/README.md +++ b/dio/README.md @@ -49,8 +49,9 @@ Depending on your configuration, this adds performance tracing and http breadcru #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) -* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) +* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) \ No newline at end of file diff --git a/dio/lib/src/dio_event_processor.dart b/dio/lib/src/dio_event_processor.dart index 3a9603abd1..afeb692be4 100644 --- a/dio/lib/src/dio_event_processor.dart +++ b/dio/lib/src/dio_event_processor.dart @@ -15,7 +15,7 @@ class DioEventProcessor implements EventProcessor { final SentryOptions _options; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { if (event is SentryTransaction) { return event; } diff --git a/dio/lib/src/failed_request_interceptor.dart b/dio/lib/src/failed_request_interceptor.dart index 994da6121e..cd36f60549 100644 --- a/dio/lib/src/failed_request_interceptor.dart +++ b/dio/lib/src/failed_request_interceptor.dart @@ -30,7 +30,7 @@ class FailedRequestInterceptor extends Interceptor { final cfr = _captureFailedRequests ?? _hub.options.captureFailedRequests; final containsStatusCode = - _failedRequestStatusCodes.containsStatusCode(err.response?.statusCode); + _failedRequestStatusCodes._containsStatusCode(err.response?.statusCode); final containsRequestTarget = containsTargetOrMatchesRegExp( _failedRequestTargets, err.requestOptions.path, @@ -49,7 +49,7 @@ class FailedRequestInterceptor extends Interceptor { } extension _ListX on List { - bool containsStatusCode(int? statusCode) { + bool _containsStatusCode(int? statusCode) { if (statusCode == null) { return false; } diff --git a/dio/lib/src/version.dart b/dio/lib/src/version.dart index 396477f00f..73fa6fc4a4 100644 --- a/dio/lib/src/version.dart +++ b/dio/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_dio'; diff --git a/dio/pubspec.yaml b/dio/pubspec.yaml index 62d1d90e77..9862c54b69 100644 --- a/dio/pubspec.yaml +++ b/dio/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_dio description: An integration which adds support for performance tracing for the Dio package. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: dio: ^5.0.0 - sentry: 7.20.0 + sentry: 8.0.0 dev_dependencies: meta: ^1.3.0 diff --git a/dio/test/dio_event_processor_test.dart b/dio/test/dio_event_processor_test.dart index 3cd060ea8e..af4a94ab8d 100644 --- a/dio/test/dio_event_processor_test.dart +++ b/dio/test/dio_event_processor_test.dart @@ -24,7 +24,7 @@ void main() { throwable: Exception(), exceptions: [fixture.sentryError(throwable)], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(event, processedEvent); }); @@ -42,7 +42,7 @@ void main() { request: SentryRequest(), exceptions: [fixture.sentryError(dioError)], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(event.throwable, processedEvent.throwable); expect(event.request, processedEvent.request); @@ -70,7 +70,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(processedEvent.throwable, event.throwable); expect(processedEvent.request?.method, 'POST'); @@ -99,7 +99,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(processedEvent.throwable, event.throwable); expect(processedEvent.request?.method, 'GET'); @@ -128,7 +128,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(processedEvent.request?.headers, {}); }); @@ -180,7 +180,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; final capturedRequest = processedEvent.request; expect(capturedRequest, isNotNull); @@ -222,7 +222,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(processedEvent.throwable, event.throwable); expect(processedEvent.contexts.response, isNotNull); @@ -263,7 +263,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(processedEvent.throwable, event.throwable); expect(processedEvent.contexts.response, isNotNull); @@ -323,7 +323,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; final capturedResponse = processedEvent.contexts.response; expect(capturedResponse, isNotNull); @@ -378,7 +378,7 @@ void main() { fixture.sentryError(dioError), ], ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; final capturedResponse = processedEvent.contexts.response; expect(capturedResponse, isNotNull); @@ -413,7 +413,7 @@ void main() { exceptions: exceptions, ); - final processedEvent = sut.apply(event) as SentryEvent; + final processedEvent = sut.apply(event, Hint()) as SentryEvent; expect(processedEvent.exceptions?.length, 2); diff --git a/dio/test/mocks.dart b/dio/test/mocks.dart index 5ed6dcd00a..30e53c5772 100644 --- a/dio/test/mocks.dart +++ b/dio/test/mocks.dart @@ -98,7 +98,7 @@ final fakeEvent = SentryEvent( /// Doesn't do anything with the events class NoOpEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { return event; } } @@ -106,7 +106,7 @@ class NoOpEventProcessor implements EventProcessor { /// Always returns null and thus drops all events class DropAllEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { return null; } } @@ -117,15 +117,15 @@ class FunctionEventProcessor implements EventProcessor { final EventProcessorFunction applyFunction; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { - return applyFunction(event, hint: hint); + SentryEvent? apply(SentryEvent event, Hint hint) { + return applyFunction(event, hint); } } typedef EventProcessorFunction = SentryEvent? Function( - SentryEvent event, { - Hint? hint, -}); + SentryEvent event, + Hint hint, +); var fakeEnvelope = SentryEnvelope.fromEvent( fakeEvent, diff --git a/drift/README.md b/drift/README.md index 43d26893e4..57b335700a 100644 --- a/drift/README.md +++ b/drift/README.md @@ -74,8 +74,9 @@ Future runApp() async { #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) * [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) diff --git a/drift/lib/src/version.dart b/drift/lib/src/version.dart index baed0fdd1b..d71a56fddd 100644 --- a/drift/lib/src/version.dart +++ b/drift/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_drift'; diff --git a/drift/pubspec.yaml b/drift/pubspec.yaml index 9d93dc877f..d468e90a12 100644 --- a/drift/pubspec.yaml +++ b/drift/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_drift description: An integration which adds support for performance tracing for the drift package. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 7.20.0 + sentry: 8.0.0 meta: ^1.3.0 drift: ^2.13.0 diff --git a/file/lib/src/version.dart b/file/lib/src/version.dart index ddc904ca24..cead856a2f 100644 --- a/file/lib/src/version.dart +++ b/file/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_file'; diff --git a/file/pubspec.yaml b/file/pubspec.yaml index 3d054c5090..3871d9ab38 100644 --- a/file/pubspec.yaml +++ b/file/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_file description: An integration which adds support for performance tracing for dart.io.File. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: windows: dependencies: - sentry: 7.20.0 + sentry: 8.0.0 meta: ^1.3.0 dev_dependencies: diff --git a/flutter/README.md b/flutter/README.md index 41e835aea8..b6b7f55d8b 100644 --- a/flutter/README.md +++ b/flutter/README.md @@ -127,8 +127,9 @@ Or [try out the Alpha version of the Sentry Dart Plugin](https://github.com/gets #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/flutter/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) * [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) diff --git a/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutter.kt b/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutter.kt index 962414c6a9..c06a8b0dc2 100644 --- a/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutter.kt +++ b/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutter.kt @@ -8,12 +8,14 @@ import java.util.Locale class SentryFlutter( private val androidSdk: String, - private val nativeSdk: String + private val nativeSdk: String, ) { - var autoPerformanceTracingEnabled = false - fun updateOptions(options: SentryAndroidOptions, data: Map) { + fun updateOptions( + options: SentryAndroidOptions, + data: Map, + ) { data.getIfNotNull("dsn") { options.dsn = it } @@ -122,7 +124,10 @@ class SentryFlutter( // Call the `completion` closure if cast to map value with `key` and type `T` is successful. @Suppress("UNCHECKED_CAST") -private fun Map.getIfNotNull(key: String, callback: (T) -> Unit) { +private fun Map.getIfNotNull( + key: String, + callback: (T) -> Unit, +) { (get(key) as? T)?.let { callback(it) } diff --git a/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt b/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt index ea9ab9d17e..5aad15a0b3 100644 --- a/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt +++ b/flutter/android/src/main/kotlin/io/sentry/flutter/SentryFlutterPlugin.kt @@ -16,10 +16,9 @@ import io.sentry.Hint import io.sentry.HubAdapter import io.sentry.Sentry import io.sentry.SentryEvent -import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.android.core.ActivityFramesTracker -import io.sentry.android.core.BuildConfig.VERSION_NAME +import io.sentry.android.core.InternalSentrySdk import io.sentry.android.core.LoadClass import io.sentry.android.core.SentryAndroid import io.sentry.android.core.SentryAndroidOptions @@ -28,10 +27,7 @@ import io.sentry.protocol.DebugImage import io.sentry.protocol.SdkVersion import io.sentry.protocol.SentryId import io.sentry.protocol.User -import java.io.File import java.lang.ref.WeakReference -import java.util.Locale -import java.util.UUID class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { private lateinit var channel: MethodChannel @@ -46,10 +42,11 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { channel = MethodChannel(flutterPluginBinding.binaryMessenger, "sentry_flutter") channel.setMethodCallHandler(this) - sentryFlutter = SentryFlutter( - androidSdk = androidSdk, - nativeSdk = nativeSdk - ) + sentryFlutter = + SentryFlutter( + androidSdk = androidSdk, + nativeSdk = nativeSdk, + ) } override fun onMethodCall(call: MethodCall, result: Result) { @@ -70,6 +67,7 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { "removeExtra" -> removeExtra(call.argument("key"), result) "setTag" -> setTag(call.argument("key"), call.argument("value"), result) "removeTag" -> removeTag(call.argument("key"), result) + "loadContexts" -> loadContexts(result) else -> result.notImplemented() } } @@ -99,18 +97,6 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { // Stub } - private fun writeEnvelope(envelope: ByteArray): Boolean { - val options = HubAdapter.getInstance().options - if (options.outboxPath.isNullOrEmpty()) { - return false - } - - val file = File(options.outboxPath, UUID.randomUUID().toString()) - file.writeBytes(envelope) - - return true - } - private fun initNativeSdk(call: MethodCall, result: Result) { if (!this::context.isInitialized) { result.error("1", "Context is null", null) @@ -142,7 +128,8 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { } val appStartTime = AppStartMetrics.getInstance().appStartTimeSpan.startTimestamp - val isColdStart = AppStartMetrics.getInstance().appStartType == AppStartMetrics.AppStartType.COLD + val isColdStart = + AppStartMetrics.getInstance().appStartType == AppStartMetrics.AppStartType.COLD if (appStartTime == null) { Log.w("Sentry", "App start won't be sent due to missing appStartTime") @@ -151,7 +138,7 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { val appStartTimeMillis = DateUtils.nanosToMillis(appStartTime.nanoTimestamp().toDouble()) val item = mapOf( "appStartTime" to appStartTimeMillis, - "isColdStart" to isColdStart + "isColdStart" to isColdStart, ) result.success(item) } @@ -192,7 +179,7 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { val frames = mapOf( "totalFrames" to total, "slowFrames" to slow, - "frozenFrames" to frozen + "frozenFrames" to frozen, ) result.success(frames) } @@ -293,20 +280,19 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { result.error("1", "The Sentry Android SDK is disabled", null) return } - - val args = call.arguments() as List? ?: listOf() + val args = call.arguments() as List? ?: listOf() if (args.isNotEmpty()) { val event = args.first() as ByteArray? - if (event != null && event.isNotEmpty()) { - if (!writeEnvelope(event)) { - result.error("2", "SentryOptions or outboxPath are null or empty", null) + val id = InternalSentrySdk.captureEnvelope(event) + if (id != null) { + result.success("") + } else { + result.error("2", "Failed to capture envelope", null) } - result.success("") return } } - result.error("3", "Envelope is null or empty", null) } @@ -344,7 +330,7 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { } private class BeforeSendCallbackImpl( - private val sdkVersion: SdkVersion? + private val sdkVersion: SdkVersion?, ) : SentryOptions.BeforeSendCallback { override fun execute(event: SentryEvent, hint: Hint): SentryEvent { setEventOriginTag(event) @@ -372,7 +358,7 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { private fun setEventEnvironmentTag( event: SentryEvent, origin: String = "android", - environment: String + environment: String, ) { event.setTag("event.origin", origin) event.setTag("event.environment", environment) @@ -391,4 +377,20 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { } } } + + private fun loadContexts(result: Result) { + val options = HubAdapter.getInstance().options + if (options !is SentryAndroidOptions) { + result.success(null) + return + } + val currentScope = InternalSentrySdk.getCurrentScope() + val serializedScope = + InternalSentrySdk.serializeScope( + context, + options, + currentScope, + ) + result.success(serializedScope) + } } diff --git a/flutter/android/src/test/kotlin/io/sentry/flutter/SentryFlutterTest.kt b/flutter/android/src/test/kotlin/io/sentry/flutter/SentryFlutterTest.kt index 3a5c8678f8..724559bb76 100644 --- a/flutter/android/src/test/kotlin/io/sentry/flutter/SentryFlutterTest.kt +++ b/flutter/android/src/test/kotlin/io/sentry/flutter/SentryFlutterTest.kt @@ -8,7 +8,6 @@ import org.junit.Before import org.junit.Test class SentryFlutterTest { - private lateinit var fixture: Fixture @Before @@ -53,7 +52,7 @@ class SentryFlutterTest { assertEquals(BuildConfig.VERSION_NAME, fixture.options.sdkVersion?.version) assertEquals( "sentry.java.android.flutter/${BuildConfig.VERSION_NAME}", - fixture.options.sentryClientName + fixture.options.sentryClientName, ) assertEquals("fixture-nativeSdk", fixture.options.nativeSdkName) @@ -73,8 +72,8 @@ class SentryFlutterTest { sut.updateOptions( fixture.options, mapOf( - "diagnosticLevel" to "warning" - ) + "diagnosticLevel" to "warning", + ), ) // Then @@ -90,8 +89,8 @@ class SentryFlutterTest { sut.updateOptions( fixture.options, mapOf( - "enableNativeCrashHandling" to false - ) + "enableNativeCrashHandling" to false, + ), ) // Then @@ -101,39 +100,39 @@ class SentryFlutterTest { } class Fixture { - var options = SentryAndroidOptions() - val data = mapOf( - "dsn" to "fixture-dsn", - "debug" to true, - "environment" to "fixture-environment", - "release" to "fixture-release", - "dist" to "fixture-dist", - "enableAutoSessionTracking" to false, - "autoSessionTrackingIntervalMillis" to 9001L, - "anrTimeoutIntervalMillis" to 9002L, - "attachThreads" to true, - "attachStacktrace" to false, - "enableAutoNativeBreadcrumbs" to false, - "maxBreadcrumbs" to 9003, - "maxCacheItems" to 9004, - "anrEnabled" to false, - "sendDefaultPii" to true, - "enableNdkScopeSync" to false, - "proguardUuid" to "fixture-proguardUuid", - "enableNativeCrashHandling" to false, - "sendClientReports" to false, - "maxAttachmentSize" to 9005L, - "enableAutoPerformanceTracing" to true, - "connectionTimeoutMillis" to 9006, - "readTimeoutMillis" to 9007 - ) + val data = + mapOf( + "dsn" to "fixture-dsn", + "debug" to true, + "environment" to "fixture-environment", + "release" to "fixture-release", + "dist" to "fixture-dist", + "enableAutoSessionTracking" to false, + "autoSessionTrackingIntervalMillis" to 9001L, + "anrTimeoutIntervalMillis" to 9002L, + "attachThreads" to true, + "attachStacktrace" to false, + "enableAutoNativeBreadcrumbs" to false, + "maxBreadcrumbs" to 9003, + "maxCacheItems" to 9004, + "anrEnabled" to false, + "sendDefaultPii" to true, + "enableNdkScopeSync" to false, + "proguardUuid" to "fixture-proguardUuid", + "enableNativeCrashHandling" to false, + "sendClientReports" to false, + "maxAttachmentSize" to 9005L, + "enableAutoPerformanceTracing" to true, + "connectionTimeoutMillis" to 9006, + "readTimeoutMillis" to 9007, + ) fun getSut(): SentryFlutter { return SentryFlutter( androidSdk = "sentry.java.android.flutter", - nativeSdk = "fixture-nativeSdk" + nativeSdk = "fixture-nativeSdk", ) } } diff --git a/flutter/config/detekt-bl.xml b/flutter/config/detekt-bl.xml index bf2e55e08b..bfd59bc97e 100644 --- a/flutter/config/detekt-bl.xml +++ b/flutter/config/detekt-bl.xml @@ -2,9 +2,8 @@ - ComplexMethod:SentryFlutterPlugin.kt$SentryFlutterPlugin$override fun onMethodCall(call: MethodCall, result: Result) CyclomaticComplexMethod:SentryFlutterPlugin.kt$SentryFlutterPlugin$override fun onMethodCall(call: MethodCall, result: Result) - LongMethod:SentryFlutter.kt$SentryFlutter$fun updateOptions(options: SentryAndroidOptions, data: Map<String, Any>) + LongMethod:SentryFlutter.kt$SentryFlutter$fun updateOptions( options: SentryAndroidOptions, data: Map<String, Any>, ) MagicNumber:MainActivity.kt$MainActivity$6_000 TooGenericExceptionCaught:MainActivity.kt$MainActivity$e: Exception TooGenericExceptionThrown:MainActivity.kt$MainActivity$throw Exception("Catch this java exception thrown from Kotlin thread!") diff --git a/flutter/example/integration_test/integration_test.dart b/flutter/example/integration_test/integration_test.dart index f292d04cfc..570b8c1fe2 100644 --- a/flutter/example/integration_test/integration_test.dart +++ b/flutter/example/integration_test/integration_test.dart @@ -203,7 +203,7 @@ void main() { class Fixture { SentryEvent? sentEvent; - FutureOr beforeSend(SentryEvent event, {Hint? hint}) async { + FutureOr beforeSend(SentryEvent event, Hint hint) async { sentEvent = event; return event; } diff --git a/flutter/example/ios/Flutter/AppFrameworkInfo.plist b/flutter/example/ios/Flutter/AppFrameworkInfo.plist index 1bdf525f9f..b7506dd05b 100644 --- a/flutter/example/ios/Flutter/AppFrameworkInfo.plist +++ b/flutter/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/flutter/example/ios/Gemfile b/flutter/example/ios/Gemfile new file mode 100644 index 0000000000..7a118b49be --- /dev/null +++ b/flutter/example/ios/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" diff --git a/flutter/example/ios/Podfile b/flutter/example/ios/Podfile index 877d653518..8cb4ddb285 100644 --- a/flutter/example/ios/Podfile +++ b/flutter/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '11.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -44,7 +44,7 @@ post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' end end end diff --git a/flutter/example/ios/Runner.xcodeproj/project.pbxproj b/flutter/example/ios/Runner.xcodeproj/project.pbxproj index 29c58327af..f8c39c79d5 100644 --- a/flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -221,7 +221,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1430; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 92B25CE92A80EB3100884BDF = { @@ -460,7 +460,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -483,6 +483,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -491,7 +492,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.example; + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.sample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -518,7 +519,7 @@ MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.sample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = NO; @@ -547,7 +548,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 16.2; MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.sample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; @@ -574,7 +575,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 16.2; MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.example.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.sample.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; @@ -631,7 +632,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -681,7 +682,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -706,6 +707,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -714,7 +716,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.example; + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.sample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -737,6 +739,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -745,7 +748,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.example; + PRODUCT_BUNDLE_IDENTIFIER = io.sentry.flutter.sample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/flutter/example/ios/Runner/Info.plist b/flutter/example/ios/Runner/Info.plist index 91d89f84d6..1023c8c85e 100644 --- a/flutter/example/ios/Runner/Info.plist +++ b/flutter/example/ios/Runner/Info.plist @@ -2,6 +2,10 @@ + ITSAppUsesNonExemptEncryption + + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -22,6 +26,8 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -41,9 +47,5 @@ UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/flutter/example/ios/RunnerTests/SentryFlutterTests.swift b/flutter/example/ios/RunnerTests/SentryFlutterTests.swift index 9dbb70ba51..057b2363b5 100644 --- a/flutter/example/ios/RunnerTests/SentryFlutterTests.swift +++ b/flutter/example/ios/RunnerTests/SentryFlutterTests.swift @@ -41,7 +41,6 @@ final class SentryFlutterTests: XCTestCase { "enableWatchdogTerminationTracking": false, "sendClientReports": false, "maxAttachmentSize": NSNumber(value: 9004), - "recordHttpBreadcrumbs": false, "captureFailedRequests": false, "enableAppHangTracking": false, "appHangTimeoutIntervalMillis": NSNumber(value: 10000) @@ -66,7 +65,6 @@ final class SentryFlutterTests: XCTestCase { XCTAssertEqual(false, fixture.options.enableWatchdogTerminationTracking) XCTAssertEqual(false, fixture.options.sendClientReports) XCTAssertEqual(9004, fixture.options.maxAttachmentSize) - XCTAssertEqual(false, fixture.options.enableNetworkBreadcrumbs) XCTAssertEqual(false, fixture.options.enableCaptureFailedRequests) XCTAssertEqual(false, fixture.options.enableAppHangTracking) XCTAssertEqual(10, fixture.options.appHangTimeoutInterval) diff --git a/flutter/example/ios/fastlane/Appfile b/flutter/example/ios/fastlane/Appfile new file mode 100644 index 0000000000..1f85333eac --- /dev/null +++ b/flutter/example/ios/fastlane/Appfile @@ -0,0 +1,7 @@ +app_identifier("io.sentry.flutter.sample") # The bundle identifier of your app + +itc_team_id("96157806") # App Store Connect Team ID +team_id("97JCY7859U") # Developer Portal Team ID + +# For more information about the Appfile, see: +# https://docs.fastlane.tools/advanced/#appfile diff --git a/flutter/example/ios/fastlane/Fastfile b/flutter/example/ios/fastlane/Fastfile new file mode 100644 index 0000000000..e14ca13d3c --- /dev/null +++ b/flutter/example/ios/fastlane/Fastfile @@ -0,0 +1,95 @@ +default_platform(:ios) + +platform :ios do + + desc "Bump Build Number" + lane :bump_build_number do + fetch_api_key() + + version_string = get_version_number(xcodeproj: "./Runner.xcodeproj") + version_parts = version_string.split(".") + + # Remove last digit if necessary + if version_parts.length > 3 + version_parts.pop + end + + new_version = version_parts.join(".") + + increment_version_number( + version_number: new_version, + xcodeproj: "./Runner.xcodeproj" + ) + increment_build_number( + build_number: latest_testflight_build_number + 1, + xcodeproj: "./Runner.xcodeproj" + ) + end + + desc "Build Release" + lane :build_release do + + setup_ci + + disable_automatic_code_signing + + sync_code_signing( + type: "development", + readonly: true, + app_identifier: ["io.sentry.flutter.sample"] + ) + + sync_code_signing( + type: "appstore", + readonly: true, + app_identifier: ["io.sentry.flutter.sample"] + ) + + update_project_provisioning( + xcodeproj: "Runner.xcodeproj", + target_filter: "Runner", + profile: ENV["sigh_io.sentry.flutter.sample_appstore_profile-path"], + build_configuration: "Release" + ) + + build_app( + workspace: "Runner.xcworkspace", + scheme: "Runner", + configuration: "Release", + clean: true, + include_symbols: true, + export_method: "app-store", + output_directory:"./build/", + export_options: { + method: "app-store", + provisioningProfiles: { + "io.sentry.flutter.sample" => ENV["sigh_io.sentry.flutter.sample_appstore_profile-name"] + } + }, + codesigning_identity: ENV["sigh_io.sentry.flutter.sample_appstore_certificate-name"], + output_name: "sentry_flutter_sample.ipa" + ) + + delete_keychain( + name: "fastlane_tmp_keychain" + ) unless is_ci + end + + desc "Upload to TestFlight" + lane :upload_testflight do + fetch_api_key() + testflight( + skip_waiting_for_build_processing: true, + ipa: "./build/sentry_flutter_sample.ipa" + ) + end + + desc "Fetch ASC API Key" + lane :fetch_api_key do + app_store_connect_api_key( + key_id: ENV["APP_STORE_CONNECT_KEY_ID"], + issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"], + key_content: ENV["APP_STORE_CONNECT_KEY"] + ) + end +end diff --git a/flutter/example/ios/fastlane/Matchfile b/flutter/example/ios/fastlane/Matchfile new file mode 100644 index 0000000000..054fef1c37 --- /dev/null +++ b/flutter/example/ios/fastlane/Matchfile @@ -0,0 +1,5 @@ +git_url("git@github.com:getsentry/codesigning.git") +storage_mode("git") +username("bot@getsentry.com") # Your Apple Developer Portal username + +# The docs are available on https://docs.fastlane.tools/actions/match diff --git a/flutter/example/lib/main.dart b/flutter/example/lib/main.dart index c7f202f4f9..86da143e31 100644 --- a/flutter/example/lib/main.dart +++ b/flutter/example/lib/main.dart @@ -496,7 +496,6 @@ class MainScaffold extends StatelessWidget { TooltipButton( onPressed: () async { final id = await Sentry.captureMessage('UserFeedback'); - if (!context.mounted) return; await showDialog( context: context, diff --git a/flutter/example/pubspec.yaml b/flutter/example/pubspec.yaml index 80bb0a3ff5..ef571be2a7 100644 --- a/flutter/example/pubspec.yaml +++ b/flutter/example/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_flutter_example description: Demonstrates how to use the sentry_flutter plugin. -version: 7.20.0 +version: 8.0.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev diff --git a/flutter/ios/sentry_flutter.podspec b/flutter/ios/sentry_flutter.podspec index c55470dc37..184a5ae7d2 100644 --- a/flutter/ios/sentry_flutter.podspec +++ b/flutter/ios/sentry_flutter.podspec @@ -19,7 +19,7 @@ Sentry SDK for Flutter with support to native through sentry-cocoa. s.dependency 'Sentry/HybridSDK', '8.21.0' s.ios.dependency 'Flutter' s.osx.dependency 'FlutterMacOS' - s.ios.deployment_target = '11.0' + s.ios.deployment_target = '12.0' # Flutter 3.7 requires 10.14 s.osx.deployment_target = '10.13' diff --git a/flutter/lib/src/event_processor/android_platform_exception_event_processor.dart b/flutter/lib/src/event_processor/android_platform_exception_event_processor.dart index c784f5b221..6570dedd81 100644 --- a/flutter/lib/src/event_processor/android_platform_exception_event_processor.dart +++ b/flutter/lib/src/event_processor/android_platform_exception_event_processor.dart @@ -16,7 +16,7 @@ class AndroidPlatformExceptionEventProcessor implements EventProcessor { final SentryFlutterOptions _options; @override - Future apply(SentryEvent event, {Hint? hint}) async { + Future apply(SentryEvent event, Hint hint) async { if (event is SentryTransaction) { return event; } diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index 615c7a4974..0ea1b731d6 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -32,9 +32,9 @@ class FlutterEnricherEventProcessor implements EventProcessor { @override Future apply( - SentryEvent event, { - Hint? hint, - }) async { + SentryEvent event, + Hint hint, + ) async { // If there's a native integration available, it probably has better // information available than Flutter. final device = diff --git a/flutter/lib/src/event_processor/flutter_exception_event_processor.dart b/flutter/lib/src/event_processor/flutter_exception_event_processor.dart index e0f4b6af14..05f9fd6595 100644 --- a/flutter/lib/src/event_processor/flutter_exception_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_exception_event_processor.dart @@ -3,7 +3,7 @@ import 'package:sentry/sentry.dart'; class FlutterExceptionEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { if (event is SentryTransaction) { return event; } diff --git a/flutter/lib/src/event_processor/native_app_start_event_processor.dart b/flutter/lib/src/event_processor/native_app_start_event_processor.dart index fd1a5ec169..f75bbc4833 100644 --- a/flutter/lib/src/event_processor/native_app_start_event_processor.dart +++ b/flutter/lib/src/event_processor/native_app_start_event_processor.dart @@ -13,7 +13,7 @@ class NativeAppStartEventProcessor implements EventProcessor { NativeAppStartEventProcessor(this._native); @override - Future apply(SentryEvent event, {Hint? hint}) async { + Future apply(SentryEvent event, Hint hint) async { if (_native.didAddAppStartMeasurement || event is! SentryTransaction) { return event; } diff --git a/flutter/lib/src/event_processor/platform_exception_event_processor.dart b/flutter/lib/src/event_processor/platform_exception_event_processor.dart index d403509ae9..2bf33e60f9 100644 --- a/flutter/lib/src/event_processor/platform_exception_event_processor.dart +++ b/flutter/lib/src/event_processor/platform_exception_event_processor.dart @@ -4,7 +4,7 @@ import 'package:sentry/sentry.dart'; /// Add code & message from [PlatformException] to [SentryException] class PlatformExceptionEventProcessor implements EventProcessor { @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { if (event is SentryTransaction) { return event; } diff --git a/flutter/lib/src/event_processor/screenshot_event_processor.dart b/flutter/lib/src/event_processor/screenshot_event_processor.dart index 48e0a4c4d6..8981afe7b1 100644 --- a/flutter/lib/src/event_processor/screenshot_event_processor.dart +++ b/flutter/lib/src/event_processor/screenshot_event_processor.dart @@ -20,7 +20,7 @@ class ScreenshotEventProcessor implements EventProcessor { sentryScreenshotWidgetGlobalKey.currentContext != null; @override - Future apply(SentryEvent event, {Hint? hint}) async { + Future apply(SentryEvent event, Hint hint) async { if (event is SentryTransaction) { return event; } @@ -78,7 +78,7 @@ class ScreenshotEventProcessor implements EventProcessor { final bytes = await _createScreenshot(); if (bytes != null) { - hint?.screenshot = SentryAttachment.fromScreenshotData(bytes); + hint.screenshot = SentryAttachment.fromScreenshotData(bytes); } return event; } diff --git a/flutter/lib/src/event_processor/widget_event_processor.dart b/flutter/lib/src/event_processor/widget_event_processor.dart index 88e9159d4d..c297585f49 100644 --- a/flutter/lib/src/event_processor/widget_event_processor.dart +++ b/flutter/lib/src/event_processor/widget_event_processor.dart @@ -6,7 +6,7 @@ import '../../sentry_flutter.dart'; class WidgetEventProcessor implements EventProcessor { @override - FutureOr apply(SentryEvent event, {Hint? hint}) { + FutureOr apply(SentryEvent event, Hint hint) { if (event is SentryTransaction) { return event; } diff --git a/flutter/lib/src/integrations/flutter_error_integration.dart b/flutter/lib/src/integrations/flutter_error_integration.dart index 3f88b99361..c1a6d57a1d 100644 --- a/flutter/lib/src/integrations/flutter_error_integration.dart +++ b/flutter/lib/src/integrations/flutter_error_integration.dart @@ -54,11 +54,8 @@ class FlutterErrorIntegration implements Integration { stackTrace: errorDetails.stack, ); - // FlutterError doesn't crash the App. - final mechanism = Mechanism( - type: 'FlutterError', - handled: true, - ); + // FlutterError doesn't crash the app, but is not handled by the user. + final mechanism = Mechanism(type: 'FlutterError', handled: false); final throwableMechanism = ThrowableMechanism(mechanism, exception); var event = SentryEvent( diff --git a/flutter/lib/src/integrations/load_contexts_integration.dart b/flutter/lib/src/integrations/load_contexts_integration.dart index c77981d35c..df8b52b97a 100644 --- a/flutter/lib/src/integrations/load_contexts_integration.dart +++ b/flutter/lib/src/integrations/load_contexts_integration.dart @@ -4,21 +4,16 @@ import 'package:flutter/services.dart'; import 'package:sentry/sentry.dart'; import '../sentry_flutter_options.dart'; -/// Load Device's Contexts from the iOS SDK. +/// Load Device's Contexts from the iOS & Android SDKs. /// -/// This integration calls the iOS SDK via Message channel to load the -/// Device's contexts before sending the event back to the iOS SDK via +/// This integration calls the iOS & Android SDKs via Message channel to load +/// the Device's contexts before sending the event back to the SDK via /// Message channel (already enriched with all the information). /// /// The Device's contexts are: /// App, Device and OS. /// -/// ps. This integration won't be run on Android because the Device's Contexts -/// is set on Android when the event is sent to the Android SDK via -/// the Message channel. -/// We intend to unify this behaviour in the future. -/// -/// This integration is only executed on iOS & MacOS Apps. +/// This integration is only executed on iOS, macOS & Android Apps. class LoadContextsIntegration extends Integration { final MethodChannel _channel; @@ -40,7 +35,7 @@ class _LoadContextsIntegrationEventProcessor implements EventProcessor { final SentryFlutterOptions _options; @override - Future apply(SentryEvent event, {Hint? hint}) async { + Future apply(SentryEvent event, Hint hint) async { try { final loadContexts = await _channel.invokeMethod('loadContexts'); @@ -163,7 +158,7 @@ class _LoadContextsIntegrationEventProcessor implements EventProcessor { ); if (beforeBreadcrumb != null) { - final processedBreadcrumb = beforeBreadcrumb(breadcrumb); + final processedBreadcrumb = beforeBreadcrumb(breadcrumb, Hint()); if (processedBreadcrumb != null) { breadcrumbs.add(processedBreadcrumb); } @@ -204,8 +199,8 @@ class _LoadContextsIntegrationEventProcessor implements EventProcessor { event = event.copyWith(sdk: sdk); } - // on iOS, captureEnvelope does not call the beforeSend callback, - // hence we need to add these tags here. + // captureEnvelope does not call the beforeSend callback, hence we need to + // add these tags here. if (event.sdk?.name == 'sentry.dart.flutter') { final tags = event.tags ?? {}; tags['event.origin'] = 'flutter'; diff --git a/flutter/lib/src/integrations/load_image_list_integration.dart b/flutter/lib/src/integrations/load_image_list_integration.dart index 8838ae0e4b..ae08d93946 100644 --- a/flutter/lib/src/integrations/load_image_list_integration.dart +++ b/flutter/lib/src/integrations/load_image_list_integration.dart @@ -54,7 +54,7 @@ class _LoadImageListIntegrationEventProcessor implements EventProcessor { final SentryFlutterOptions _options; @override - Future apply(SentryEvent event, {Hint? hint}) async { + Future apply(SentryEvent event, Hint hint) async { if (event.needsSymbolication()) { try { // we call on every event because the loaded image list is cached diff --git a/flutter/lib/src/sentry_flutter.dart b/flutter/lib/src/sentry_flutter.dart index 6c4e2c243b..1931e86981 100644 --- a/flutter/lib/src/sentry_flutter.dart +++ b/flutter/lib/src/sentry_flutter.dart @@ -160,7 +160,7 @@ mixin SentryFlutter { // Will enrich events with device context, native packages and integrations if (platformChecker.hasNativeIntegration && !platformChecker.isWeb && - (platform.isIOS || platform.isMacOS)) { + (platform.isIOS || platform.isMacOS || platform.isAndroid)) { integrations.add(LoadContextsIntegration(channel)); } diff --git a/flutter/lib/src/user_interaction/sentry_user_interaction_widget.dart b/flutter/lib/src/user_interaction/sentry_user_interaction_widget.dart index 45af49b14d..018f750a2e 100644 --- a/flutter/lib/src/user_interaction/sentry_user_interaction_widget.dart +++ b/flutter/lib/src/user_interaction/sentry_user_interaction_widget.dart @@ -317,7 +317,8 @@ class _SentryUserInteractionWidgetState void _onTappedAt(Offset position) { final tappedWidget = _getElementAt(position); - final keyValue = tappedWidget?.element.widget.key?.toStringValue(); + final keyValue = + WidgetUtils.toStringValue(tappedWidget?.element.widget.key); if (tappedWidget == null || keyValue == null) { return; } diff --git a/flutter/lib/src/version.dart b/flutter/lib/src/version.dart index e9f6c225d1..233de685ed 100644 --- a/flutter/lib/src/version.dart +++ b/flutter/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The default SDK name reported to Sentry.io in the submitted events. const String sdkName = 'sentry.dart.flutter'; diff --git a/flutter/lib/src/view_hierarchy/sentry_tree_walker.dart b/flutter/lib/src/view_hierarchy/sentry_tree_walker.dart index 2a85bf49be..41b03f4808 100644 --- a/flutter/lib/src/view_hierarchy/sentry_tree_walker.dart +++ b/flutter/lib/src/view_hierarchy/sentry_tree_walker.dart @@ -281,7 +281,7 @@ class _TreeWalker { return SentryViewHierarchyElement( element.widget.runtimeType.toString(), depth: element.depth, - identifier: element.widget.key?.toStringValue(), + identifier: WidgetUtils.toStringValue(element.widget.key), width: width, height: height, x: x, diff --git a/flutter/lib/src/view_hierarchy/view_hierarchy_event_processor.dart b/flutter/lib/src/view_hierarchy/view_hierarchy_event_processor.dart index 99d43ad982..c3fefe52f5 100644 --- a/flutter/lib/src/view_hierarchy/view_hierarchy_event_processor.dart +++ b/flutter/lib/src/view_hierarchy/view_hierarchy_event_processor.dart @@ -1,7 +1,7 @@ import '../../sentry_flutter.dart'; import 'sentry_tree_walker.dart'; -/// A [EventProcessor] that renders an ASCII represention of the entire view +/// A [EventProcessor] that renders an ASCII representation of the entire view /// hierarchy of the application when an error happens and includes it as an /// attachment to the [Hint]. class SentryViewHierarchyEventProcessor implements EventProcessor { @@ -10,7 +10,7 @@ class SentryViewHierarchyEventProcessor implements EventProcessor { final SentryFlutterOptions _options; @override - SentryEvent? apply(SentryEvent event, {Hint? hint}) { + SentryEvent? apply(SentryEvent event, Hint hint) { if (event is SentryTransaction) { return event; } @@ -31,7 +31,7 @@ class SentryViewHierarchyEventProcessor implements EventProcessor { final viewHierarchy = SentryAttachment.fromViewHierarchy(sentryViewHierarchy); - hint?.viewHierarchy = viewHierarchy; + hint.viewHierarchy = viewHierarchy; return event; } } diff --git a/flutter/lib/src/widget_utils.dart b/flutter/lib/src/widget_utils.dart index 9d63b8d5a3..97d51a990a 100644 --- a/flutter/lib/src/widget_utils.dart +++ b/flutter/lib/src/widget_utils.dart @@ -1,8 +1,12 @@ import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; -extension WidgetExtension on Key { - String? toStringValue() { - final key = this; +@internal +class WidgetUtils { + static String? toStringValue(Key? key) { + if (key == null) { + return null; + } if (key is ValueKey) { return key.value; } else if (key is ValueKey) { diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 34f6a7713d..040bbc47cb 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -1,5 +1,5 @@ name: sentry_flutter -version: 7.20.0 +version: 8.0.0 description: Sentry SDK for Flutter. This package aims to support different Flutter targets by relying on the many platforms supported by Sentry with native SDKs. homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart @@ -23,7 +23,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - sentry: 7.20.0 + sentry: 8.0.0 package_info_plus: '>=1.0.0 <8.0.0' meta: ^1.3.0 ffi: ^2.0.0 diff --git a/flutter/test/android_platform_exception_event_processor_test.dart b/flutter/test/android_platform_exception_event_processor_test.dart index f98bedbe26..5e916f06a3 100644 --- a/flutter/test/android_platform_exception_event_processor_test.dart +++ b/flutter/test/android_platform_exception_event_processor_test.dart @@ -26,8 +26,8 @@ void main() { group(AndroidPlatformExceptionEventProcessor, () { test('exception is correctly parsed', () async { - final platformExceptionEvent = - await fixture.processor.apply(fixture.eventWithPlatformStackTrace); + final platformExceptionEvent = await fixture.processor + .apply(fixture.eventWithPlatformStackTrace, Hint()); final exceptions = platformExceptionEvent!.exceptions!; expect(exceptions.length, 3); @@ -54,8 +54,8 @@ void main() { test( 'Dart thread is current and not crashed if Android exception is present', () async { - final platformExceptionEvent = - await fixture.processor.apply(fixture.eventWithPlatformStackTrace); + final platformExceptionEvent = await fixture.processor + .apply(fixture.eventWithPlatformStackTrace, Hint()); final exceptions = platformExceptionEvent!.exceptions!; expect(exceptions.length, 3); @@ -65,8 +65,8 @@ void main() { }); test('platformexception has Android thread attached', () async { - final platformExceptionEvent = - await fixture.processor.apply(fixture.eventWithPlatformStackTrace); + final platformExceptionEvent = await fixture.processor + .apply(fixture.eventWithPlatformStackTrace, Hint()); final exceptions = platformExceptionEvent!.exceptions!; expect(exceptions.length, 3); @@ -85,8 +85,8 @@ void main() { fixture.options.attachThreads = false; final threadCount = fixture.eventWithPlatformStackTrace.threads?.length; - final platformExceptionEvent = - await fixture.processor.apply(fixture.eventWithPlatformStackTrace); + final platformExceptionEvent = await fixture.processor + .apply(fixture.eventWithPlatformStackTrace, Hint()); final exceptions = platformExceptionEvent!.exceptions!; expect(exceptions.length, 3); @@ -103,14 +103,15 @@ void main() { throwable: null, ); - final platformExceptionEvent = await fixture.processor.apply(event); + final platformExceptionEvent = + await fixture.processor.apply(event, Hint()); expect(event, platformExceptionEvent); }); test('does nothing if PlatformException has no stackTrace', () async { - final platformExceptionEvent = - await fixture.processor.apply(fixture.eventWithoutPlatformStackTrace); + final platformExceptionEvent = await fixture.processor + .apply(fixture.eventWithoutPlatformStackTrace, Hint()); expect(fixture.eventWithoutPlatformStackTrace, platformExceptionEvent); }); diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index 5fbc1d7034..892e7ff517 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -39,7 +39,7 @@ void main() { binding: () => tester.binding, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); debugBrightnessOverride = null; debugDefaultTargetPlatformOverride = null; @@ -65,7 +65,7 @@ void main() { binding: () => tester.binding, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); debugBrightnessOverride = null; debugDefaultTargetPlatformOverride = null; @@ -81,7 +81,7 @@ void main() { binding: () => tester.binding, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); final accessibility = event?.contexts['accessibility']; @@ -98,7 +98,7 @@ void main() { binding: () => tester.binding, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); final culture = event?.contexts.culture; @@ -133,7 +133,7 @@ void main() { }, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.culture?.locale, 'de-DE'); }); @@ -144,7 +144,7 @@ void main() { ); tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.resumed); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); final app = event?.contexts.app; @@ -157,7 +157,7 @@ void main() { ); tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.inactive); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); final app = event?.contexts.app; @@ -175,7 +175,7 @@ void main() { final event = SentryEvent(); event.contexts.app = SentryApp(name: appName); - final mutatedEvent = await enricher.apply(event); + final mutatedEvent = await enricher.apply(event, Hint()); final app = mutatedEvent?.contexts.app; @@ -190,7 +190,7 @@ void main() { hasNativeIntegration: true, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device, isNull); }); @@ -202,7 +202,7 @@ void main() { hasNativeIntegration: false, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); expect(event?.contexts.device, isNotNull); }); @@ -212,7 +212,7 @@ void main() { binding: () => tester.binding, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); final flutterRuntime = event?.contexts.runtimes .firstWhere((element) => element.name == 'Flutter'); @@ -236,7 +236,7 @@ void main() { checker: pair.key, ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); final flutterRuntime = event?.contexts.runtimes .firstWhere((element) => element.name == 'Flutter'); @@ -264,7 +264,7 @@ void main() { ), ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); expect(event?.modules, { 'foo_package': 'unknown', @@ -292,7 +292,7 @@ void main() { ), ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); expect(event?.modules, null); }); @@ -316,7 +316,7 @@ void main() { ), ); - final event = await enricher.apply(SentryEvent()); + final event = await enricher.apply(SentryEvent(), Hint()); expect(event?.modules, {'foo_package': 'unknown'}); }); @@ -341,7 +341,7 @@ void main() { hasNativeIntegration: false, ); - final event = await enricher.apply(fakeEvent); + final event = await enricher.apply(fakeEvent, Hint()); // contexts.device expect( @@ -401,7 +401,7 @@ void main() { final enricher = fixture.getSut( binding: () => tester.binding, ); - final event = await enricher.apply(eventWithContextsApp); + final event = await enricher.apply(eventWithContextsApp, Hint()); expect(event?.contexts.app?.viewNames, ['fixture-currentRouteName']); }); diff --git a/flutter/test/event_processor/flutter_exception_event_processor_test.dart b/flutter/test/event_processor/flutter_exception_event_processor_test.dart index aaca15e2af..8dc4f5c528 100644 --- a/flutter/test/event_processor/flutter_exception_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_exception_event_processor_test.dart @@ -20,6 +20,7 @@ void main() { uri: Uri.parse('https://example.org/foo/bar?foo=bar'), ), ), + Hint(), ); expect(event?.request, isNotNull); diff --git a/flutter/test/event_processor/platform_exception_event_processor_test.dart b/flutter/test/event_processor/platform_exception_event_processor_test.dart index d4bf2d9c99..ecc3d7130b 100644 --- a/flutter/test/event_processor/platform_exception_event_processor_test.dart +++ b/flutter/test/event_processor/platform_exception_event_processor_test.dart @@ -26,7 +26,7 @@ void main() { var event = SentryEvent(exceptions: [sentryException]); final sut = fixture.getSut(); - event = (sut.apply(event))!; + event = (sut.apply(event, Hint()))!; expect(event.exceptions?.first.mechanism?.data["code"], "fixture-code"); expect(event.exceptions?.first.mechanism?.data["message"], @@ -46,7 +46,7 @@ void main() { var event = SentryEvent(exceptions: [sentryException]); final sut = fixture.getSut(); - event = (sut.apply(event))!; + event = (sut.apply(event, Hint()))!; expect(event.exceptions?.first.mechanism?.type, "platformException"); }); diff --git a/flutter/test/event_processor/screenshot_event_processor_test.dart b/flutter/test/event_processor/screenshot_event_processor_test.dart index 763c0e0ca3..2c1d0a4adc 100644 --- a/flutter/test/event_processor/screenshot_event_processor_test.dart +++ b/flutter/test/event_processor/screenshot_event_processor_test.dart @@ -40,7 +40,7 @@ void main() { final throwable = Exception(); event = SentryEvent(throwable: throwable); hint = Hint(); - await sut.apply(event, hint: hint); + await sut.apply(event, hint); expect(hint.screenshot != null, added); if (expectedMaxWidthOrHeight != null) { diff --git a/flutter/test/event_processor/widget_event_processor_test.dart b/flutter/test/event_processor/widget_event_processor_test.dart index 5e93e288ff..4744b58ad2 100644 --- a/flutter/test/event_processor/widget_event_processor_test.dart +++ b/flutter/test/event_processor/widget_event_processor_test.dart @@ -30,7 +30,7 @@ void main() { app: SentryApp(), ), ); - event = await sut.apply(event); + event = await sut.apply(event, Hint()); expect(event?.contexts.app?.textScale, 1.0); }); diff --git a/flutter/test/integrations/flutter_error_integration_test.dart b/flutter/test/integrations/flutter_error_integration_test.dart index 6c479fdf39..401b606bc4 100644 --- a/flutter/test/integrations/flutter_error_integration_test.dart +++ b/flutter/test/integrations/flutter_error_integration_test.dart @@ -70,7 +70,7 @@ void main() { final throwableMechanism = event.throwableMechanism as ThrowableMechanism; expect(throwableMechanism.mechanism.type, 'FlutterError'); - expect(throwableMechanism.mechanism.handled, true); + expect(throwableMechanism.mechanism.handled, false); expect(throwableMechanism.throwable, exception); expect(event.contexts['flutter_error_details']['library'], 'sentry'); @@ -102,7 +102,7 @@ void main() { final throwableMechanism = event.throwableMechanism as ThrowableMechanism; expect(throwableMechanism.mechanism.type, 'FlutterError'); - expect(throwableMechanism.mechanism.handled, true); + expect(throwableMechanism.mechanism.handled, false); expect(event.contexts['flutter_error_details']['library'], 'sentry'); expect(event.contexts['flutter_error_details']['context'], @@ -126,7 +126,7 @@ void main() { final throwableMechanism = event.throwableMechanism as ThrowableMechanism; expect(throwableMechanism.mechanism.type, 'FlutterError'); - expect(throwableMechanism.mechanism.handled, true); + expect(throwableMechanism.mechanism.handled, false); expect(throwableMechanism.mechanism.data['hint'], isNull); expect(event.contexts['flutter_error_details'], isNull); diff --git a/flutter/test/integrations/load_contexts_integration_test.dart b/flutter/test/integrations/load_contexts_integration_test.dart index 29aed18027..7b57eb572a 100644 --- a/flutter/test/integrations/load_contexts_integration_test.dart +++ b/flutter/test/integrations/load_contexts_integration_test.dart @@ -58,7 +58,8 @@ void main() { final integration = LoadContextsIntegration(fixture.methodChannel); integration.call(fixture.hub, fixture.options); - event = (await fixture.options.eventProcessors.first.apply(event))!; + event = + (await fixture.options.eventProcessors.first.apply(event, Hint()))!; expect(event.breadcrumbs!.length, 1); expect(event.breadcrumbs!.first.message, 'native'); @@ -83,7 +84,8 @@ void main() { final integration = LoadContextsIntegration(fixture.methodChannel); integration.call(fixture.hub, fixture.options); - event = (await fixture.options.eventProcessors.first.apply(event))!; + event = + (await fixture.options.eventProcessors.first.apply(event, Hint()))!; expect(event.breadcrumbs!.length, 1); expect(event.breadcrumbs!.first.message, 'event'); @@ -91,7 +93,7 @@ void main() { test('apply beforeBreadcrumb to native breadcrumbs', () async { fixture.options.enableScopeSync = true; - fixture.options.beforeBreadcrumb = (breadcrumb, {hint}) { + fixture.options.beforeBreadcrumb = (breadcrumb, hint) { if (breadcrumb?.message == 'native-mutated') { return breadcrumb?.copyWith(message: 'native-mutated-applied'); } else { @@ -119,7 +121,8 @@ void main() { final integration = LoadContextsIntegration(fixture.methodChannel); integration.call(fixture.hub, fixture.options); - event = (await fixture.options.eventProcessors.first.apply(event))!; + event = + (await fixture.options.eventProcessors.first.apply(event, Hint()))!; expect(event.breadcrumbs!.length, 1); expect(event.breadcrumbs!.first.message, 'native-mutated-applied'); diff --git a/flutter/test/integrations/load_contexts_integrations_test.dart b/flutter/test/integrations/load_contexts_integrations_test.dart index c6bb98f0b7..6de2d32e8d 100644 --- a/flutter/test/integrations/load_contexts_integrations_test.dart +++ b/flutter/test/integrations/load_contexts_integrations_test.dart @@ -81,7 +81,7 @@ void main() { e.contexts.operatingSystem = SentryOperatingSystem(theme: 'theme1'); e.contexts.app = SentryApp(inForeground: true); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(fixture.called, true); expect(event?.contexts.device?.name, 'Device1'); @@ -121,7 +121,7 @@ void main() { final e = SentryEvent(contexts: eventContexts, user: SentryUser(id: 'myId')); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(fixture.called, true); expect(event?.contexts.device?.name, 'eDevice'); @@ -145,7 +145,8 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect( event?.sdk?.packages.any((element) => element.name == 'native-package'), @@ -169,7 +170,8 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect( event?.sdk?.integrations @@ -189,7 +191,8 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect( event?.sdk?.packages @@ -210,7 +213,8 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect( event?.sdk?.packages @@ -239,7 +243,7 @@ void main() { integration(fixture.hub, fixture.options); final e = SentryEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event, isNotNull); }); @@ -252,7 +256,8 @@ void main() { final eventSdk = getSdkVersion(name: 'sentry.dart.flutter'); final e = getEvent(sdk: eventSdk); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.tags?['event.origin'], 'flutter'); expect(event?.tags?['event.environment'], 'dart'); @@ -270,7 +275,8 @@ void main() { sdk: eventSdk, tags: {'a': 'b'}, ); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.tags?['event.origin'], 'flutter'); expect(event?.tags?['event.environment'], 'dart'); @@ -285,7 +291,8 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(tags: {}); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = + await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.tags?.containsKey('event.origin'), false); expect(event?.tags?.containsKey('event.environment'), false); @@ -298,7 +305,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(tags: {'key': 'flutter', 'key-a': 'flutter'}); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.tags?['key'], 'flutter'); expect(event?.tags?['key-a'], 'flutter'); @@ -311,7 +318,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(extra: {'key': 'flutter', 'key-a': 'flutter'}); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); // ignore: deprecated_member_use expect(event?.extra?['key'], 'flutter'); @@ -326,7 +333,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.user?.id, '196E065A-AAF7-409A-9A6C-A81F40274CB9'); expect(event?.user?.username, 'fixture-username'); @@ -340,7 +347,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(user: SentryUser(id: 'abc')); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.user?.id, 'abc'); }); @@ -350,7 +357,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.dist, 'fixture-dist'); }); @@ -360,7 +367,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(dist: 'abc'); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.dist, 'abc'); }); @@ -370,7 +377,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.environment, 'fixture-environment'); }); @@ -380,7 +387,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(environment: 'abc'); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.environment, 'abc'); }); @@ -391,7 +398,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(fingerprint: ['fingerprint-a', 'fingerprint-b']); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.fingerprint, ['fingerprint-a', 'fingerprint-b']); }); @@ -401,7 +408,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.level, SentryLevel.error); }); @@ -411,7 +418,7 @@ void main() { integration(fixture.hub, fixture.options); final e = getEvent(level: SentryLevel.fatal); - final event = await fixture.options.eventProcessors.first.apply(e); + final event = await fixture.options.eventProcessors.first.apply(e, Hint()); expect(event?.level, SentryLevel.fatal); }); diff --git a/flutter/test/integrations/load_image_list_test.dart b/flutter/test/integrations/load_image_list_test.dart index 085bbcd3dc..b02acc94f3 100644 --- a/flutter/test/integrations/load_image_list_test.dart +++ b/flutter/test/integrations/load_image_list_test.dart @@ -135,7 +135,7 @@ void main() { final ep = fixture.options.eventProcessors.first; SentryEvent? event = _getEvent(); - event = await ep.apply(event); + event = await ep.apply(event, Hint()); expect(1, event!.debugMeta!.images.length); }); @@ -146,7 +146,7 @@ void main() { sut.call(fixture.hub, fixture.options); final ep = fixture.options.eventProcessors.first; SentryEvent? event = _getEvent(); - event = await ep.apply(event); + event = await ep.apply(event, Hint()); final image = event!.debugMeta!.images.first; diff --git a/flutter/test/integrations/native_app_start_integration_test.dart b/flutter/test/integrations/native_app_start_integration_test.dart index 135d90f34b..70b088cfec 100644 --- a/flutter/test/integrations/native_app_start_integration_test.dart +++ b/flutter/test/integrations/native_app_start_integration_test.dart @@ -31,7 +31,8 @@ void main() { final transaction = SentryTransaction(tracer); final processor = fixture.options.eventProcessors.first; - final enriched = await processor.apply(transaction) as SentryTransaction; + final enriched = + await processor.apply(transaction, Hint()) as SentryTransaction; final measurement = enriched.measurements['app_start_cold']!; expect(measurement.value, 10); @@ -50,8 +51,10 @@ void main() { final processor = fixture.options.eventProcessors.first; - var enriched = await processor.apply(transaction) as SentryTransaction; - var secondEnriched = await processor.apply(enriched) as SentryTransaction; + var enriched = + await processor.apply(transaction, Hint()) as SentryTransaction; + var secondEnriched = + await processor.apply(enriched, Hint()) as SentryTransaction; expect(secondEnriched.measurements.length, 1); }); @@ -69,8 +72,10 @@ void main() { final processor = fixture.options.eventProcessors.first; - var enriched = await processor.apply(transaction) as SentryTransaction; - var secondEnriched = await processor.apply(enriched) as SentryTransaction; + var enriched = + await processor.apply(transaction, Hint()) as SentryTransaction; + var secondEnriched = + await processor.apply(enriched, Hint()) as SentryTransaction; expect(secondEnriched.measurements.length, 2); expect(secondEnriched.measurements.containsKey(measurement.name), true); @@ -86,7 +91,8 @@ void main() { final transaction = SentryTransaction(tracer); final processor = fixture.options.eventProcessors.first; - final enriched = await processor.apply(transaction) as SentryTransaction; + final enriched = + await processor.apply(transaction, Hint()) as SentryTransaction; expect(enriched.measurements.isEmpty, true); }); diff --git a/flutter/test/load_image_list_test.dart b/flutter/test/load_image_list_test.dart index 0afff01b97..345d913887 100644 --- a/flutter/test/load_image_list_test.dart +++ b/flutter/test/load_image_list_test.dart @@ -127,7 +127,7 @@ void main() { final ep = fixture.options.eventProcessors.first; SentryEvent? event = _getEvent(); - event = await ep.apply(event); + event = await ep.apply(event, Hint()); expect(1, event!.debugMeta!.images.length); }); @@ -138,7 +138,7 @@ void main() { sut.call(fixture.hub, fixture.options); final ep = fixture.options.eventProcessors.first; SentryEvent? event = _getEvent(); - event = await ep.apply(event); + event = await ep.apply(event, Hint()); final image = event!.debugMeta!.images.first; diff --git a/flutter/test/sentry_flutter_test.dart b/flutter/test/sentry_flutter_test.dart index f01c9a8d3f..e06938da90 100644 --- a/flutter/test/sentry_flutter_test.dart +++ b/flutter/test/sentry_flutter_test.dart @@ -32,9 +32,10 @@ final nonWebIntegrations = [ OnErrorIntegration, ]; -// These should only be added to Android +// These should be added to Android final androidIntegrations = [ LoadImageListIntegration, + LoadContextsIntegration, ]; // These should be added to iOS and macOS diff --git a/flutter/test/view_hierarchy/view_hierarchy_event_processor_test.dart b/flutter/test/view_hierarchy/view_hierarchy_event_processor_test.dart index 6900ba5589..7743e8ebc6 100644 --- a/flutter/test/view_hierarchy/view_hierarchy_event_processor_test.dart +++ b/flutter/test/view_hierarchy/view_hierarchy_event_processor_test.dart @@ -26,7 +26,7 @@ void main() { exceptions: [SentryException(type: 'type', value: 'value')]); final hint = Hint(); - sut.apply(event, hint: hint); + sut.apply(event, hint); expect(hint.viewHierarchy, isNotNull); }); @@ -42,7 +42,7 @@ void main() { final event = SentryEvent(throwable: StateError('error')); final hint = Hint(); - sut.apply(event, hint: hint); + sut.apply(event, hint); expect(hint.viewHierarchy, isNotNull); }); @@ -58,7 +58,7 @@ void main() { final event = SentryEvent(); final hint = Hint(); - sut.apply(event, hint: hint); + sut.apply(event, hint); expect(hint.viewHierarchy, isNull); }); @@ -74,7 +74,7 @@ void main() { final event = SentryEvent(); final hint = Hint(); - sut.apply(event, hint: hint); + sut.apply(event, hint); expect(hint.viewHierarchy, isNull); }); diff --git a/hive/README.md b/hive/README.md index a5347c31a4..b67e9e4f7b 100644 --- a/hive/README.md +++ b/hive/README.md @@ -78,8 +78,9 @@ class Person { #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) * [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) diff --git a/hive/lib/src/version.dart b/hive/lib/src/version.dart index d0079c0f70..524aa89e7f 100644 --- a/hive/lib/src/version.dart +++ b/hive/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_hive'; diff --git a/hive/pubspec.yaml b/hive/pubspec.yaml index 161e7796d9..6aeaed7f68 100644 --- a/hive/pubspec.yaml +++ b/hive/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_hive description: An integration which adds support for performance tracing for the hive package. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -17,7 +17,7 @@ platforms: web: dependencies: - sentry: 7.20.0 + sentry: 8.0.0 hive: ^2.2.3 meta: ^1.3.0 diff --git a/isar/README.md b/isar/README.md index 5405c8e43e..011e8e834f 100644 --- a/isar/README.md +++ b/isar/README.md @@ -76,8 +76,9 @@ Future runApp() async { #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) * [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) diff --git a/isar/lib/src/version.dart b/isar/lib/src/version.dart index a61930b879..7410567886 100644 --- a/isar/lib/src/version.dart +++ b/isar/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_isar'; diff --git a/isar/pubspec.yaml b/isar/pubspec.yaml index 53aa85a5f8..fb83755493 100644 --- a/isar/pubspec.yaml +++ b/isar/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_isar description: An integration which adds support for performance tracing for the isar package. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -20,7 +20,7 @@ platforms: dependencies: isar: ^3.1.0 isar_flutter_libs: ^3.1.0 # contains Isar Core - sentry: 7.20.0 + sentry: 8.0.0 meta: ^1.3.0 path: ^1.8.3 diff --git a/logging/README.md b/logging/README.md index 0b4b4fcfef..488ebb8adf 100644 --- a/logging/README.md +++ b/logging/README.md @@ -43,8 +43,9 @@ void initApp() { #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) -* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) +* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) \ No newline at end of file diff --git a/logging/lib/src/version.dart b/logging/lib/src/version.dart index fbbea58108..21a66180d1 100644 --- a/logging/lib/src/version.dart +++ b/logging/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_logging'; diff --git a/logging/pubspec.yaml b/logging/pubspec.yaml index 04d4232f8f..b9855f47de 100644 --- a/logging/pubspec.yaml +++ b/logging/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_logging description: An integration which adds support for recording log from the logging package. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/dart/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -19,7 +19,7 @@ platforms: dependencies: logging: ^1.0.0 - sentry: 7.20.0 + sentry: 8.0.0 dev_dependencies: lints: ^3.0.0 diff --git a/min_version_test/ios/Podfile b/min_version_test/ios/Podfile index 88359b225f..2c068c404b 100644 --- a/min_version_test/ios/Podfile +++ b/min_version_test/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/sqflite/README.md b/sqflite/README.md index ed2b3c4f9d..ff5774ba74 100644 --- a/sqflite/README.md +++ b/sqflite/README.md @@ -62,8 +62,9 @@ Future insertProducts() async { #### Resources -* [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/dart/) -* [![Forum](https://img.shields.io/badge/forum-sentry-green.svg)](https://forum.sentry.io/c/sdks) -* [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr) +* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/) +* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/) +* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions) +* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K) * [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry) -* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) +* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry) \ No newline at end of file diff --git a/sqflite/lib/src/version.dart b/sqflite/lib/src/version.dart index 5b98e5939e..d0fae42df4 100644 --- a/sqflite/lib/src/version.dart +++ b/sqflite/lib/src/version.dart @@ -1,5 +1,5 @@ /// The SDK version reported to Sentry.io in the submitted events. -const String sdkVersion = '7.20.0'; +const String sdkVersion = '8.0.0'; /// The package name reported to Sentry.io in the submitted events. const String packageName = 'pub:sentry_sqflite'; diff --git a/sqflite/pubspec.yaml b/sqflite/pubspec.yaml index e8d317c214..32d060abef 100644 --- a/sqflite/pubspec.yaml +++ b/sqflite/pubspec.yaml @@ -1,6 +1,6 @@ name: sentry_sqflite description: An integration which adds support for performance tracing for the sqflite package. -version: 7.20.0 +version: 8.0.0 homepage: https://docs.sentry.io/platforms/flutter/ repository: https://github.com/getsentry/sentry-dart issue_tracker: https://github.com/getsentry/sentry-dart/issues @@ -15,7 +15,7 @@ platforms: macos: dependencies: - sentry: 7.20.0 + sentry: 8.0.0 sqflite: ^2.0.0 sqflite_common: ^2.0.0 meta: ^1.3.0