Skip to content

fix: prevent multiple submissions in NewSyncProfileCubit - #96

Merged
SuperMuel merged 3 commits into
mainfrom
feature/prevent-double-submission
Sep 21, 2025
Merged

SuperMuel merged 3 commits into
mainfrom
feature/prevent-double-submission

Conversation

@SuperMuel

@SuperMuel SuperMuel commented Sep 21, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Bug Fixes

    • Prevented concurrent submit actions in the new sync profile flow. Additional taps while a submission is in progress are ignored, avoiding duplicate requests, inconsistent states, and unexpected errors for a more stable submission experience.
  • Chores

    • Bumped app version to 0.2.3 to reflect these fixes and improvements.

@coderabbitai

coderabbitai Bot commented Sep 21, 2025

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds an early isSubmitting guard and reorders isSubmitting toggling in submit() of new_sync_profile_cubit to prevent concurrent submissions and ensure isSubmitting resets on validation failure. Also increments app version from 0.2.2 to 0.2.3 in pubspec.yaml.

Changes

Cohort / File(s) Summary
Submission concurrency & state flow
syncademic_app/lib/screens/new_sync_profile/cubit/new_sync_profile_cubit.dart
Reworked submit(): set isSubmitting = true early; short-circuit if state.isSubmitting is already true; run canSubmit() after setting isSubmitting; on validation failure set isSubmitting = false and emit submitError; removed previous late emission of isSubmitting = true.
Version bump
syncademic_app/pubspec.yaml
Bumped package version from 0.2.2 to 0.2.3.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant C as NewSyncProfileCubit
  participant S as Backend/Service

  U->>C: submit()
  alt Already submitting
    C->>C: Check state.isSubmitting == true
    Note right of C #F9F6EE: Early return (no-op)
  else Not submitting
    C->>C: Emit isSubmitting = true
    C->>C: canSubmit() validation
    alt Invalid
      C->>C: Emit isSubmitting = false and submitError
      C-->>U: Emit validation error state
    else Valid
      C->>S: Perform submission
      S-->>C: Response
      C->>C: Emit isSubmitting = false and result state
      C-->>U: Emit success or error state
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I thump my paw: “One at a time!” I say,
No double hops to lead astray.
A gentle bump—0.2.3 in tow,
Validate, submit, then steady go.
With whiskers twitching, all is right. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix: prevent multiple submissions in NewSyncProfileCubit" clearly and concisely captures the primary change—preventing duplicate submissions in the NewSyncProfileCubit—using a conventional "fix:" prefix and specific component name, so a reviewer scanning history will understand the main intent.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/prevent-double-submission

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.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @SuperMuel, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a crucial fix to prevent users from inadvertently triggering multiple submissions within the NewSyncProfileCubit. By implementing a simple check at the beginning of the submit function, the system now ensures that only one submission process can be active at any given time, enhancing the stability and user experience of the profile creation workflow.

Highlights

  • Prevent Multiple Submissions: A guard clause has been added to the submit() method in NewSyncProfileCubit to prevent concurrent submissions. If the state indicates that a submission is already in progress, the method will now return immediately.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request aims to prevent multiple submissions in NewSyncProfileCubit by adding a guard clause at the beginning of the submit method. While this is a good intention, the current implementation is not fully protected against race conditions. I've left a comment with a suggestion to make the fix more robust by ensuring the isSubmitting state is updated immediately. This will prevent multiple submissions from being processed if the submit method is invoked multiple times in quick succession.

Comment on lines +241 to +243
if (state.isSubmitting) {
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This check is a good step towards preventing multiple submissions. However, a race condition is still possible. If submit() is called multiple times in quick succession (e.g., due to rapid UI taps before the button is disabled), both calls might pass this check before the state is updated with isSubmitting: true.

To make this fully robust against race conditions, you should emit a state with isSubmitting: true immediately after this guard clause, and before any asynchronous operations (await).

For example:

Future<void> submit() async {
  if (state.isSubmitting) {
    return;
  }
  emit(state.copyWith(isSubmitting: true));

  if (!state.canSubmit()) {
    emit(state.copyWith(
      isSubmitting: false, // Also reset here
      submitError: 'Please fill all the required fields.',
    ));
    return;
  }

  try {
    // ... async submission logic ...
    emit(state.copyWith(isSubmitting: false, submittedSuccessfully: true));
  } catch (e) {
    emit(state.copyWith(isSubmitting: false, submitError: e.toString()));
  }
}

By setting isSubmitting: true synchronously at the beginning, you effectively "lock" the submission process and prevent any concurrent executions from starting.

@github-actions

github-actions Bot commented Sep 21, 2025

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 9a924ef):

https://syncademic-36c18--pr96-feature-prevent-doub-397dkx9c.web.app

(expires Sun, 28 Sep 2025 16:45:20 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 1427d2ca23ba5ec56b241548ca0f0f1eb2be2ea1

@SuperMuel
SuperMuel merged commit 3f47c90 into main Sep 21, 2025
3 of 4 checks passed
@SuperMuel
SuperMuel deleted the feature/prevent-double-submission branch September 21, 2025 16:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (2)
syncademic_app/lib/screens/new_sync_profile/cubit/new_sync_profile_cubit.dart (2)

100-112: Listener callback should not be async/Future

providerAccountSelected returns Future<void> but is used as a Stream.listen callback (expects void Function(T)). Make it synchronous.

-  Future<void> providerAccountSelected(
-          ProviderAccount? providerAccount) async =>
+  void providerAccountSelected(
+          ProviderAccount? providerAccount) =>
       emit(
         providerAccount == null
           ? state.copyWith(
               providerAccount: null,
               providerAccountError: 'No provider account selected.',
             )
           : state.copyWith(
               providerAccount: providerAccount,
               providerAccountError: null,
             ),
       );

241-289: Reset isSubmitting in a finally block and clear stale submit flags when starting submit

Exceptions thrown while building the payload (before the current try/catch) can leave isSubmitting true — clear submitError/submittedSuccessfully at start and guarantee isSubmitting is reset in a finally.

File: syncademic_app/lib/screens/new_sync_profile/cubit/new_sync_profile_cubit.dart (submit method)

  • At submit start: emit(state.copyWith(isSubmitting: true, submitError: null, submittedSuccessfully: false)).
  • Wrap payload construction + service call in try { … } finally { emit(state.copyWith(isSubmitting: false)); } — move success/error emits into the inner try/catch and avoid setting isSubmitting there.
  • Add tests: simulate an exception between start and service call to assert isSubmitting → false; test double-submit (first call pending) to assert single service invocation and proper state transitions.
🧹 Nitpick comments (1)
syncademic_app/lib/screens/new_sync_profile/cubit/new_sync_profile_cubit.dart (1)

148-178: Async method should return Future<void>

void authorizeBackend() async prevents callers from awaiting completion or catching errors. Prefer Future<void>.

-  void authorizeBackend() async {
+  Future<void> authorizeBackend() 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 892a0cc and 9a924ef.

📒 Files selected for processing (1)
  • syncademic_app/lib/screens/new_sync_profile/cubit/new_sync_profile_cubit.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). (2)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: build_and_preview
🔇 Additional comments (1)
syncademic_app/lib/screens/new_sync_profile/cubit/new_sync_profile_cubit.dart (1)

241-253: Early re-entrancy guard + immediate lock: good fix

The guard and the immediate isSubmitting: true emit eliminate concurrent submissions on rapid taps.

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.

1 participant