From 2ec15d4b348903f19879860aaa8a7ab153faa784 Mon Sep 17 00:00:00 2001 From: LucasZF Date: Tue, 20 Oct 2026 23:26:43 +0100 Subject: [PATCH] fix(flutter): Allow empty associatedEventId SentryFeedbackForm asserted that associatedEventId is never SentryId.empty(), but Hub.captureMessage/captureEvent return the empty id whenever the capture is not sent (network error, disabled hub, beforeSend drop). Opening the form with that id crashed debug and profile builds. Treat an empty id the same as null (no association) instead. Fixes #4042 Co-Authored-By: Claude Opus 5.5 --- .../src/feedback/sentry_feedback_form.dart | 8 +++- .../feedback/sentry_feedback_form_test.dart | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/feedback/sentry_feedback_form.dart b/packages/flutter/lib/src/feedback/sentry_feedback_form.dart index b950b6e3db..3ab08cfe0c 100644 --- a/packages/flutter/lib/src/feedback/sentry_feedback_form.dart +++ b/packages/flutter/lib/src/feedback/sentry_feedback_form.dart @@ -13,12 +13,16 @@ import '../utils/internal_logger.dart'; /// A form for submitting user feedback to Sentry. class SentryFeedbackForm extends StatefulWidget { + /// An empty [associatedEventId] (e.g. returned when the original event + /// could not be captured) is treated as no association. SentryFeedbackForm({ super.key, - this.associatedEventId, + SentryId? associatedEventId, this.screenshot, @internal Hub? hub, - }) : assert(associatedEventId != const SentryId.empty()), + }) : associatedEventId = associatedEventId == const SentryId.empty() + ? null + : associatedEventId, _hub = hub ?? HubAdapter() { assert( _hub.options is SentryFlutterOptions, diff --git a/packages/flutter/test/feedback/sentry_feedback_form_test.dart b/packages/flutter/test/feedback/sentry_feedback_form_test.dart index e7b554a43e..b5d45e6b47 100644 --- a/packages/flutter/test/feedback/sentry_feedback_form_test.dart +++ b/packages/flutter/test/feedback/sentry_feedback_form_test.dart @@ -514,6 +514,48 @@ void main() { ), ).called(1); }); + + testWidgets( + 'submits feedback without association when associatedEventId is empty', + (tester) async { + await fixture.pumpFeedbackForm( + tester, + (hub) => SentryFeedbackForm( + hub: hub, + associatedEventId: const SentryId.empty(), + ), + ); + + when( + fixture.hub.captureFeedback( + any, + hint: anyNamed('hint'), + withScope: anyNamed('withScope'), + ), + ).thenAnswer( + (_) async => SentryId.fromId('1988bb1b6f0d4c509e232f0cb9aaeaea'), + ); + + await tester.enterText( + find.byKey(ValueKey('sentry_feedback_message_textfield')), + "fixture-message", + ); + await tester.tap(find.text('Send Bug Report')); + await tester.pumpAndSettle(); + + verify( + fixture.hub.captureFeedback( + argThat( + predicate( + (feedback) => feedback.associatedEventId == null, + ), + ), + hint: anyNamed('hint'), + withScope: anyNamed('withScope'), + ), + ).called(1); + }, + ); }); group('$SentryFeedbackForm localization', () {