Skip to content

Sheet bugs fixes and code refactor#183

Merged
kumarpalsinh25 merged 1 commit intomainfrom
kumar/sheet-bugs-fixes
Dec 12, 2025
Merged

Sheet bugs fixes and code refactor#183
kumarpalsinh25 merged 1 commit intomainfrom
kumar/sheet-bugs-fixes

Conversation

@kumarpalsinh25
Copy link
Copy Markdown
Collaborator

@kumarpalsinh25 kumarpalsinh25 commented Dec 12, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Centralized error handling for sheet operations (create, delete, update, share) ensures more reliable error recovery and consistent failure management.
  • Improvements

    • Refined navigation behavior to respect context state and compact view settings for better UX consistency.

✏️ Tip: You can customize this high-level summary in your review settings.

- Implement `runFirestoreOperation` for robust error handling across all Firestore calls in `sheet_providers`.
- Refine sheet list stream processing and subscription logic for better clarity.
- Adjust `onTap` behavior in `SheetListItemWidget` to conditionally pop the context only when in compact mode.
- Simplify empty state check in `SheetListWidget`.
@kumarpalsinh25 kumarpalsinh25 marked this pull request as ready for review December 12, 2025 11:30
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 12, 2025

Walkthrough

Centralized Firestore error handling by introducing a runFirestoreOperation wrapper across all CRUD methods in the sheet provider. Refactored stream subscription, added null-user guard validation, and made minor UI logic adjustments to sheet list widgets including type refinement and conditional navigation behavior.

Changes

Cohort / File(s) Summary
Sheet Provider Error Handling
lib/features/sheet/providers/sheet_providers.dart
Added firestore_error_handler import; wrapped all CRUD operations (add, delete, update) with runFirestoreOperation for centralized error handling; refactored stream subscription to map documents directly to SheetModel; added null-user guard on addSheet; updated all methods to execute Firestore calls inside the wrapper function.
Sheet List UI Refinements
lib/features/sheet/widgets/sheet_list_item_widget.dart
Added default value for isCompact parameter; refined onTap behavior to only pop navigation when canPop() and isCompact is true; refined _buildContentSection parameter type from dynamic to SheetModel.
Formatting Update
lib/features/sheet/widgets/sheet_list_widget.dart
Condensed empty sheet list return statement from multi-line to single-line format.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20-25 minutes

  • Focus areas:
    • Verify runFirestoreOperation wrapper correctly handles all error scenarios and maintains expected Firestore operation behavior across all refactored CRUD methods.
    • Confirm null-user guard logic in addSheet prevents unintended side effects.
    • Validate that stream subscription changes preserve original filtering/mapping intent after removing whereType.
    • Review onTap navigation logic in sheet list item to ensure conditional pop behavior is correct for compact vs. non-compact layouts.

Possibly related PRs

Suggested reviewers

  • anisha-e10

Poem

🐰 With errors caught and wrapped up tight,
Firestore calls now feel so right,
No more scattered error ways,
One handler rules all our days,
Robust sheets, refactored clean,
Best refactor we've seen!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Sheet bugs fixes and code refactor' is generic and lacks specificity about the main changes, making it difficult to understand the primary focus from the changeset. Consider a more specific title that highlights the primary change, such as 'Add Firestore error handling to sheet providers' or 'Refactor sheet providers with centralized error handling'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kumar/sheet-bugs-fixes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/features/sheet/providers/sheet_providers.dart (1)

79-171: Wrapping write ops with runFirestoreOperation is a solid consistency improvement.
One exception: updateSheetShareInfo uses raw 'sharedBy' / 'message' keys—prefer constants (e.g., FirestoreFieldConstants.*) to avoid schema drift/typos and keep fields consistent across the app.

🧹 Nitpick comments (2)
lib/features/sheet/providers/sheet_providers.dart (2)

60-60: onDispose cancellation is the right place for cleanup.
One minor note: StreamSubscription.cancel() returns a Future; if you’re intentionally not awaiting, consider unawaited(_subscription?.cancel()); for clarity.


68-76: addSheet: early-return on null user is safe, but consider surfacing a failure.
Silently returning can hide UI/logic bugs (e.g., button appears to work but doesn’t). If your UX expects feedback, consider returning a bool/Result or throwing a domain error that runFirestoreOperation can render.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e111cc and 531cfcd.

📒 Files selected for processing (3)
  • lib/features/sheet/providers/sheet_providers.dart (4 hunks)
  • lib/features/sheet/widgets/sheet_list_item_widget.dart (3 hunks)
  • lib/features/sheet/widgets/sheet_list_widget.dart (1 hunks)
⏰ 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). (8)
  • GitHub Check: ios
  • GitHub Check: linux
  • GitHub Check: format
  • GitHub Check: android
  • GitHub Check: Test zoe_native plugin
  • GitHub Check: windows
  • GitHub Check: test
  • GitHub Check: macos
🔇 Additional comments (5)
lib/features/sheet/widgets/sheet_list_widget.dart (1)

35-35: Early-return for empty state is clean and equivalent.
No behavioral change; improves readability.

lib/features/sheet/widgets/sheet_list_item_widget.dart (3)

14-18: Making isCompact optional w/ default is good API ergonomics.
Just ensure no callsites expected it to be required (should be caught at compile time).


31-34: Potential nav fragility: pop() then push() in the same callback.
Depending on route teardown timing, using the same context after pop() can be flaky. Consider using a “replace” style nav for compact mode, or schedule the push() after the pop (e.g., microtask), or navigate from a parent/root context.


90-90: Tightening _buildContentSection to SheetModel is a clear win.
Improves safety and readability.

lib/features/sheet/providers/sheet_providers.dart (1)

54-58: Double-check onError path: throwing inside runFirestoreOperation may crash the stream.
If runFirestoreOperation rethrows (or returns a Future here and errors become unhandled), the provider may get into noisy crash/rebuild loops. Consider handling/logging without rethrowing from the listener, or ensure the wrapper definitively absorbs + reports errors safely in this context.

Comment on lines +48 to +53
_subscription = query.snapshots().listen(
(snapshot) {
state = snapshot.docs
.map((doc) => SheetModel.fromJson(doc.data()))
.toList();
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

High-risk: snapshot mapping may drop Firestore doc ID.
If SheetModel.fromJson(doc.data()) doesn’t reliably populate id (common if id isn’t stored as a field), sheet.id can become empty/wrong and break navigation/updates. Prefer injecting doc.id into the model mapping (or using a dedicated fromFirestore that takes DocumentSnapshot).

🤖 Prompt for AI Agents
In lib/features/sheet/providers/sheet_providers.dart around lines 48 to 53, the
snapshot mapping uses SheetModel.fromJson(doc.data()) which may drop the
Firestore document ID; update the mapping to ensure the doc.id is preserved by
either (a) passing a merged map into the constructor (e.g., final data =
{...doc.data(), 'id': doc.id} then call SheetModel.fromJson(data)), or (b) add a
SheetModel.fromFirestore(DocumentSnapshot doc) that sets id = doc.id and use
that here; adjust the state assignment to use the chosen approach so every
SheetModel includes the Firestore document ID.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/features/sheet/providers/sheet_providers.dart (1)

6-60: Stream mapping needs exception handling, and the onError handler returns an unawaited future.

The listen callback can throw if SheetModel.fromJson encounters invalid data (e.g., malformed color, type mismatch). Stream onError won't catch exceptions from the callback—they'll propagate and potentially crash the app. Additionally, runFirestoreOperation returns a Future that is never awaited in the onError handler, which can trigger lint warnings.

The doc.data() already contains the id field (stored by toJson() at line 125 of sheet_model.dart), so no manual doc.id injection is needed.

Wrap the mapping in a try-catch and mark the future as unawaited:

 _subscription = query.snapshots().listen(
-  (snapshot) {
-    state = snapshot.docs
-        .map((doc) => SheetModel.fromJson(doc.data()))
-        .toList();
-  },
-  onError: (error, stackTrace) => runFirestoreOperation(
-    ref,
-    () => Error.throwWithStackTrace(error, stackTrace),
-  ),
+  (snapshot) {
+    try {
+      state = snapshot.docs
+          .map((doc) => SheetModel.fromJson(doc.data()))
+          .toList();
+    } catch (error, stackTrace) {
+      unawaited(runFirestoreOperation(
+        ref,
+        () => Error.throwWithStackTrace(error, stackTrace),
+      ));
+    }
+  },
+  onError: (error, stackTrace) {
+    unawaited(runFirestoreOperation(
+      ref,
+      () => Error.throwWithStackTrace(error, stackTrace),
+    ));
+  },
 );

Ensure unawaited is imported from dart:async.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e111cc and 531cfcd.

📒 Files selected for processing (3)
  • lib/features/sheet/providers/sheet_providers.dart (4 hunks)
  • lib/features/sheet/widgets/sheet_list_item_widget.dart (3 hunks)
  • lib/features/sheet/widgets/sheet_list_widget.dart (1 hunks)
⏰ 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). (7)
  • GitHub Check: ios
  • GitHub Check: linux
  • GitHub Check: android
  • GitHub Check: Test zoe_native plugin
  • GitHub Check: windows
  • GitHub Check: test
  • GitHub Check: macos
🔇 Additional comments (4)
lib/features/sheet/widgets/sheet_list_widget.dart (1)

35-35: Empty-state early return is fine (no behavior change).

lib/features/sheet/widgets/sheet_list_item_widget.dart (2)

14-18: Constructor default for isCompact improves call-site ergonomics.


90-90: Typing _buildContentSection as SheetModel is a solid cleanup (drops dynamic).

lib/features/sheet/providers/sheet_providers.dart (1)

68-171: Centralizing Firestore writes via runFirestoreOperation is a net win; verify the silent userId == null path is intended.
Wrapping all CRUD calls should make failures more consistent. The only behavior change to double-check is addSheet: it now returns early when userId is null (Line 70). If callers expect an error state/UI feedback, consider surfacing a handled error (via the same error handler) rather than a no-op.

Comment on lines 31 to 34
onTap: () {
if (context.canPop()) context.pop();
if (context.canPop() && isCompact) context.pop();
context.push(AppRoutes.sheet.route.replaceAll(':sheetId', sheet.id));
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid using context for navigation after pop() (possible deactivated context).

       onTap: () {
-        if (context.canPop() && isCompact) context.pop();
-        context.push(AppRoutes.sheet.route.replaceAll(':sheetId', sheet.id));
+        final router = GoRouter.of(context);
+        if (router.canPop() && isCompact) router.pop();
+        router.push(AppRoutes.sheet.route.replaceAll(':sheetId', sheet.id));
       },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onTap: () {
if (context.canPop()) context.pop();
if (context.canPop() && isCompact) context.pop();
context.push(AppRoutes.sheet.route.replaceAll(':sheetId', sheet.id));
},
onTap: () {
final router = GoRouter.of(context);
if (router.canPop() && isCompact) router.pop();
router.push(AppRoutes.sheet.route.replaceAll(':sheetId', sheet.id));
},
🤖 Prompt for AI Agents
In lib/features/sheet/widgets/sheet_list_item_widget.dart around lines 31 to 34,
the code calls context.pop() and then immediately uses the same context to push
a new route which can fail because the context may be deactivated after pop; fix
by computing the target route string first, perform the pop if needed, and defer
the push to after the pop (e.g., schedule the push with Future.microtask or
WidgetsBinding.instance.addPostFrameCallback) so you don’t use the popped
context synchronously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants