feat: optimize cant-do error handling#292
Conversation
- Replace if-else chain with Map lookup for better performance - Add missing cant-do error types with proper localization
WalkthroughCentralizes cant-do notification messages with a new CantDoNotificationMapper, replaces ad-hoc cant-do branching in NotificationListenerWidget, prevents duplicate temporary cantDo notifications in AbstractMostroNotifier, switches outOfRangeFiatAmount to a parameterless localization getter, and updates EN/ES/IT ARB strings. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UI as App UI
participant Notifier as AbstractMostroNotifier
participant Listener as NotificationListenerWidget
participant Mapper as CantDoNotificationMapper
participant Local as Localization (S)
UI->>Notifier: handleEvent(event)
Notifier-->>Listener: dispatch notification payload
alt payload.action == cantDo
Listener->>Mapper: getMessage(context, cantDoReason)
Mapper->>Local: lookup localized string
Local-->>Mapper: localized cant-do message
Mapper-->>Listener: message (or generic fallback)
Listener-->>UI: show cant-do notification
else payload.action != cantDo
Listener->>Local: getLocalizedTitle(action)
Local-->>Listener: title
Listener-->>UI: show temporary notification
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
lib/shared/widgets/notification_listener_widget.dart (3)
9-9: Prevent instantiation of static-only mapper.Make the class non-instantiable.
-class CantDoNotificationMapper { +class CantDoNotificationMapper { + CantDoNotificationMapper._();
11-27: Nit: avoid the null-bang on S.of(context) if not needed.If the generated l10n API returns non-null, drop
!to satisfy lints. Apply across entries.- 'pending_order_exists': (context) => S.of(context)!.pendingOrderExists, + 'pending_order_exists': (context) => S.of(context).pendingOrderExists,
29-36: Log unknown cant-do reasons for observability.Keep user-facing fallback, but log the unhandled reason to catch gaps.
- // Fallback to generic cant-do message - return NotificationMessageMapper.getLocalizedTitle(context, mostro.Action.cantDo); + // Fallback to generic cant-do message + assert(() { + // Helps surface missing mappings in debug builds. + // ignore: avoid_print + print('[CantDoNotificationMapper] Unhandled cant-do reason: $cantDoReason'); + return true; + }()); + return NotificationMessageMapper.getLocalizedTitle(context, mostro.Action.cantDo);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
lib/features/order/notfiers/abstract_mostro_notifier.dart(1 hunks)lib/features/trades/widgets/mostro_message_detail_widget.dart(1 hunks)lib/l10n/intl_en.arb(1 hunks)lib/l10n/intl_es.arb(1 hunks)lib/l10n/intl_it.arb(1 hunks)lib/shared/widgets/notification_listener_widget.dart(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_en.arblib/l10n/intl_es.arblib/l10n/intl_it.arb
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/trades/widgets/mostro_message_detail_widget.dartlib/features/order/notfiers/abstract_mostro_notifier.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/trades/widgets/mostro_message_detail_widget.dartlib/features/order/notfiers/abstract_mostro_notifier.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/trades/widgets/mostro_message_detail_widget.dartlib/features/order/notfiers/abstract_mostro_notifier.dart
🧠 Learnings (4)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_en.arblib/l10n/intl_es.arb
📚 Learning: 2025-07-08T05:40:47.527Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
Applied to files:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-07-20T23:33:17.689Z
Learnt from: Catrya
PR: MostroP2P/mobile#215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future<void>. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.
Applied to files:
lib/features/order/notfiers/abstract_mostro_notifier.dart
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.
Applied to files:
lib/features/order/notfiers/abstract_mostro_notifier.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (9)
lib/features/order/notfiers/abstract_mostro_notifier.dart (1)
333-336: Good guard to stop duplicate cantDo notifications.Skipping cantDo in the default branch prevents the extra generic “order update” temp notification. Matches the PR goal to eliminate dupes.
lib/features/trades/widgets/mostro_message_detail_widget.dart (1)
253-253: Replace remaining parameterized call tooutOfRangeFiatAmount
In lib/data/models/enums/cant_do_reason.dart:18, update the invocationoutOfRangeFiatAmount('out_of_range_fiat_amount')to the parameterless getter to match the ARB/API change.
⛔ Skipped due to learnings
Learnt from: chebizarro PR: MostroP2P/mobile#127 File: lib/data/models/cant_do.dart:10-27 Timestamp: 2025-07-08T05:40:47.527Z Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.lib/l10n/intl_en.arb (2)
136-136: Copy update OK.Reworded
cantCreateUserreads naturally and matches other locales.
139-139: Placeholders removed as intended.
outOfRangeFiatAmountnow generic; consistent with code changes.lib/l10n/intl_es.arb (1)
139-139: Placeholders removed as intended.
outOfRangeFiatAmountnow generic; consistent with code changes.lib/l10n/intl_it.arb (2)
136-136: Copy update OK.Reworded
cantCreateUsermatches intent and tone.
139-139: Placeholders removed as intended.
outOfRangeFiatAmountnow generic; consistent with code changes.lib/shared/widgets/notification_listener_widget.dart (2)
9-27: Great call: centralized cant-do mapping.This removes branching, keeps all messages localized, and simplifies maintenance. Looks correct.
21-22: Good alignment with updated i18n API.Using the parameterless
outOfRangeFiatAmountgetter matches the ARB/l10n change.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
lib/l10n/intl_es.arb (1)
136-136: Brand capitalization fixed — looks good.“Mostro” is correctly capitalized now and the phrasing reads naturally.
lib/shared/widgets/notification_listener_widget.dart (1)
74-81: Guardnext.valuesto avoid runtime exceptions on malformed payloads.If
valuesis null or not a Map, current code will throw. Safely check before indexing.- if (next.action == mostro.Action.cantDo) { - final reason = next.values['action']; + if (next.action == mostro.Action.cantDo) { + final rawValues = next.values; + final reason = rawValues is Map ? rawValues['action'] : null; if (reason is String && reason.isNotEmpty) { message = CantDoNotificationMapper.getMessage(context, reason); } else { // Fallback if the payload is malformed or type changes message = NotificationMessageMapper.getLocalizedTitle(context, mostro.Action.cantDo); } } else {
🧹 Nitpick comments (2)
lib/shared/widgets/notification_listener_widget.dart (2)
10-30: Good centralization; add remaining cant-do mappings for full coverage.You already cover most reasons; include the rest so we don’t fall back to generic when we have specific strings.
static final _messageMap = <String, String Function(BuildContext)>{ @@ 'invalid_order_status': (context) => S.of(context)!.invalidOrderStatus, + 'invalid_payment_request': (context) => S.of(context)!.invalidPaymentRequest, + 'invalid_text_message': (context) => S.of(context)!.invalidTextMessage, + 'invalid_parameters': (context) => S.of(context)!.invalidParameters, + 'is_not_your_dispute': (context) => S.of(context)!.isNotYourDispute, + 'dispute_creation_error': (context) => S.of(context)!.disputeCreationError, + 'not_found': (context) => S.of(context)!.notFound, + 'invalid_dispute_status': (context) => S.of(context)!.invalidDisputeStatus, + 'invalid_action': (context) => S.of(context)!.invalidAction, };
32-42: Fallback is correct; consider a tiny unit test.Add a test asserting a known reason returns the specific message and an unknown reason hits the generic fallback.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
lib/l10n/intl_es.arb(1 hunks)lib/shared/widgets/notification_listener_widget.dart(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_es.arb
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/shared/widgets/notification_listener_widget.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/shared/widgets/notification_listener_widget.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/shared/widgets/notification_listener_widget.dart
🧠 Learnings (3)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_es.arb
📚 Learning: 2025-07-08T05:40:47.527Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
Applied to files:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Use Riverpod for state management with Notifiers encapsulating business logic; access data only through repositories
Applied to files:
lib/shared/widgets/notification_listener_widget.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (2)
lib/l10n/intl_es.arb (1)
139-139: Resolved: locale consistency and call sites verified
EN and IT ARB entries foroutOfRangeFiatAmountare now parameterless and no Dart call sites pass arguments.lib/shared/widgets/notification_listener_widget.dart (1)
3-3: Logger import makes sense.Used for unknown cant-do reasons; fine to keep.
Summary by CodeRabbit
Bug Fixes
Localization
Refactor