Skip to content

Fix: awaiting function for gift generation - #691

Merged
shashilo merged 10 commits into
developfrom
alex/fixing-gift-generation
Nov 19, 2025
Merged

Fix: awaiting function for gift generation#691
shashilo merged 10 commits into
developfrom
alex/fixing-gift-generation

Conversation

@alexappleget

@alexappleget alexappleget commented Nov 18, 2025

Copy link
Copy Markdown
Collaborator

Description

After:

Button disabled for gift drawing now with toast notification

Closes #[ticketnumber]

[optional] Screenshots

Recording.2025-11-19.122011.mp4

Pre-submission checklist

  • Code builds and passes locally
  • PR title follows Conventional Commit format (e.g. test #001: created unit test for __ component)
  • Request reviews from the Peer Code Reviewers and Senior+ Code Reviewers groups
  • Thread has been created in Discord and PR is linked in gis-code-questions

Summary by CodeRabbit

  • New Features

    • Loading state with spinner and disabled button while a gift exchange draw runs
    • Toast notifications informing users to keep their browser open during the draw and reporting success/failure
  • Bug Fixes

    • Drawing workflow now surfaces errors reliably (sequential handling instead of fire-and-forget)
  • Tests

    • Added a test case for disabling the draw button when a draw is in progress✏️ Tip: You can customize this high-level summary in your review settings.✏️ Tip: You can customize this high-level summary in your review settings.

@alexappleget
alexappleget requested review from a team and shashilo and removed request for a team November 18, 2025 19:02
@vercel

vercel Bot commented Nov 18, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
elecretanta Ready Ready Preview Comment Nov 19, 2025 7:48pm
elecretanta-storybook Ready Ready Preview Comment Nov 19, 2025 7:48pm
elecretanta-unit-test Ready Ready Preview Comment Nov 19, 2025 7:48pm

@coderabbitai

coderabbitai Bot commented Nov 18, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds drawing state and toast feedback to GiftExchangeHeader, updates the draw button UI/attributes, changes drawGiftExchange to await per-member suggestion generation (propagating errors), and adds a new test case for the draw-button disabled state that contains no assertions.

Changes

Cohort / File(s) Summary
GiftExchangeHeader Component
components/GiftExchangeHeader/GiftExchangeHeader.tsx
Adds isDrawing state and useToast; shows a success toast when drawing begins and an error toast on failure; disables draw button while drawing; renders LoadingSpinner when drawing; updates button data-testid strings and adds min-w-40 class.
GiftExchangeHeader Tests
components/GiftExchangeHeader/GiftExchangeHeader.test.tsx
Adds a new test case "should disable the draw gift exchange button when the gift exchange is being drawn" that renders the component with mockGiftExchangeDataPending and mockMembersData. The test contains no assertions or interactions.
Gift Exchange Utility
lib/drawGiftExchange.ts
Replaces a fire-and-forget .catch call with an explicit await for generateAndStoreSuggestions inside the per-member loop so rejections propagate to the outer try/catch (sequential execution).

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Header as GiftExchangeHeader
    participant Toast as Toast Service
    participant Util as drawGiftExchange
    participant API as generateAndStoreSuggestions

    User->>Header: Click "Draw Gift Exchange"
    Header->>Header: set isDrawing = true
    Header->>Toast: show success toast ("keep browser open")
    Header->>Util: call drawGiftExchange()

    rect rgb(230,245,255)
    Note over Util,API: For each member: sequential await
    Util->>API: await generateAndStoreSuggestions(member)
    API-->>Util: success / error
    end

    alt Success
        Header->>Header: set isDrawing = false
        Header->>User: button re-enabled
    else Error
        Header->>Header: set isDrawing = false
        Header->>Toast: show error toast
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Check toast usage and message correctness in GiftExchangeHeader.tsx.
  • Verify UI state transitions (isDrawing) and accessibility attributes for the draw button.
  • Confirm lib/drawGiftExchange.ts sequential await behavior and error flow.
  • Review the added test to determine intended assertions (it currently has none).

Poem

🐰 I tapped the button, waited still,
A spinner hummed upon the sill,
A toast bade me keep the tab in sight,
One-by-one suggestions took their flight,
Hop-hop — new pairings stitched tonight.

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 accurately reflects the main technical change: adding await to the generateAndStoreSuggestions function in drawGiftExchange.ts, which is the core fix addressing proper error handling in gift generation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch alex/fixing-gift-generation

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)

267-269: Fix typo in dialog title.

"gift exchangee" should be "gift exchange".

                       <AlertDialogTitle>
-                        Are you sure you want to start gift exchangee?
+                        Are you sure you want to start gift exchange?
                       </AlertDialogTitle>
🧹 Nitpick comments (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)

138-142: Consider using a more semantically appropriate toast variant.

The informational message about keeping the browser open uses ToastVariants.Success, which typically indicates successful completion. An Info, Loading, or Default variant (if available) would better convey the ongoing nature of the operation.

     toast({
-      variant: ToastVariants.Success,
+      variant: ToastVariants.Info, // or ToastVariants.Default if Info is unavailable
       title: '',
       description: 'Please keep this browser open until our elves complete the gift drawing.',
     });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 43e0035 and 3a8700b.

📒 Files selected for processing (3)
  • components/GiftExchangeHeader/GiftExchangeHeader.test.tsx (1 hunks)
  • components/GiftExchangeHeader/GiftExchangeHeader.tsx (5 hunks)
  • lib/drawGiftExchange.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
components/GiftExchangeHeader/GiftExchangeHeader.test.tsx (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)
  • GiftExchangeHeader (59-316)
lib/drawGiftExchange.ts (1)
lib/generateAndStoreSuggestions.ts (1)
  • generateAndStoreSuggestions (19-139)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (2)
hooks/use-toast.ts (2)
  • useToast (243-267)
  • toast (188-232)
components/LoadingSpinner/LoadingSpinner.tsx (1)
  • LoadingSpinner (3-21)
🔇 Additional comments (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)

136-165: LGTM—drawing state and error handling are well implemented.

The drawing state management correctly:

  • Disables the button during the operation
  • Shows visual feedback via LoadingSpinner
  • Resets state on error for retry capability
  • Reloads on success (no need to reset state)

Comment thread components/GiftExchangeHeader/GiftExchangeHeader.test.tsx
Comment thread lib/drawGiftExchange.ts
Comment on lines 94 to +103
// Fire and forget suggestions with error handling
// hacky way to avoid waiting for all suggestions to be generated
// avoids timeout issues
generateAndStoreSuggestions(
await generateAndStoreSuggestions(
supabase,
exchangeId,
giver.user_id,
recipient.user_id,
exchange.budget,
).catch((error) => {
throw new SupabaseError('Failed to generate suggestions', 500, error);
});
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Sequential awaiting of AI generation may cause timeouts and degrade reliability.

Replacing the fire-and-forget pattern with await inside the loop means the drawing process now blocks on potentially slow OpenAI API calls for each member sequentially. This change:

  1. Reintroduces timeout risk that the previous implementation explicitly avoided (per the comments)
  2. Amplifies latency linearly with member count (e.g., 10 members × ~5s per OpenAI call = 50+ seconds)
  3. Changes error semantics: a failure in suggestion generation for any single member now fails the entire drawing, whereas previously it was isolated

Consider reverting to the fire-and-forget approach with proper error logging, or implement parallel processing with Promise.allSettled to generate suggestions concurrently while still completing the drawing regardless of individual suggestion failures.

-      await generateAndStoreSuggestions(
+      generateAndStoreSuggestions(
         supabase,
         exchangeId,
         giver.user_id,
         recipient.user_id,
         exchange.budget,
-      );
+      ).catch((error) => {
+        console.error('Failed to generate suggestions for member:', giver.user_id, error);
+      });
📝 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
// Fire and forget suggestions with error handling
// hacky way to avoid waiting for all suggestions to be generated
// avoids timeout issues
generateAndStoreSuggestions(
await generateAndStoreSuggestions(
supabase,
exchangeId,
giver.user_id,
recipient.user_id,
exchange.budget,
).catch((error) => {
throw new SupabaseError('Failed to generate suggestions', 500, error);
});
);
// Fire and forget suggestions with error handling
// hacky way to avoid waiting for all suggestions to be generated
// avoids timeout issues
generateAndStoreSuggestions(
supabase,
exchangeId,
giver.user_id,
recipient.user_id,
exchange.budget,
).catch((error) => {
console.error('Failed to generate suggestions for member:', giver.user_id, error);
});
🤖 Prompt for AI Agents
In lib/drawGiftExchange.ts around lines 94 to 103, the code now awaits
generateAndStoreSuggestions sequentially inside the loop which reintroduces
timeout/latency risk and makes a single suggestion failure abort the whole draw;
change this to a non-blocking approach by either restoring the original
fire-and-forget call (call generateAndStoreSuggestions without await and
capture/log errors inside that function) or run suggestion generation
concurrently and resiliently using Promise.allSettled over an array of
per-member generate calls so the draw completes regardless of individual
failures and errors are logged for debugging.

Comment thread lib/drawGiftExchange.ts
Comment on lines 94 to 96
// Fire and forget suggestions with error handling
// hacky way to avoid waiting for all suggestions to be generated
// avoids timeout issues

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove outdated comments.

These comments reference the previous fire-and-forget implementation but no longer reflect the current sequential await behavior.

-      // Fire and forget suggestions with error handling
-      // hacky way to avoid waiting for all suggestions to be generated
-      // avoids timeout issues
       await generateAndStoreSuggestions(
📝 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
// Fire and forget suggestions with error handling
// hacky way to avoid waiting for all suggestions to be generated
// avoids timeout issues
await generateAndStoreSuggestions(
🤖 Prompt for AI Agents
In lib/drawGiftExchange.ts around lines 94 to 96, remove the outdated comments
that reference a fire-and-forget implementation and timeout avoidance since the
code now performs sequential awaits; replace or delete those lines so comments
accurately reflect the current sequential behavior (or leave no comment if
unnecessary).

Comment thread components/GiftExchangeHeader/GiftExchangeHeader.tsx
shashilo
shashilo previously approved these changes Nov 19, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)

269-269: Fix typo in dialog title.

"gift exchangee" should be "gift exchange" (remove extra 'e').

-Are you sure you want to start gift exchangee?
+Are you sure you want to start gift exchange?
🧹 Nitpick comments (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)

138-142: Consider toast title and variant choice.

The toast has an empty title and uses Success variant before the operation completes. Consider:

  • Adding a meaningful title like "Drawing in Progress"
  • Using a neutral or info variant since the operation hasn't succeeded yet
 toast({
-  variant: ToastVariants.Success,
-  title: '',
+  variant: ToastVariants.Info,
+  title: 'Drawing in Progress',
   description: 'Please keep this browser open until our elves complete the gift drawing.',
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a8700b and 897927e.

📒 Files selected for processing (1)
  • components/GiftExchangeHeader/GiftExchangeHeader.tsx (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (2)
hooks/use-toast.ts (2)
  • useToast (243-267)
  • toast (188-232)
components/LoadingSpinner/LoadingSpinner.tsx (1)
  • LoadingSpinner (3-21)
🔇 Additional comments (5)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (5)

35-37: LGTM: Imports added correctly.

The new imports support the loading state UI and toast notifications.


65-66: LGTM: State and hook initialization.

The isDrawing state and toast hook are properly initialized for managing the draw process feedback.


164-166: LGTM: State reset in finally block.

The finally block correctly ensures isDrawing is reset regardless of success or failure. This addresses the previous review feedback.


241-249: LGTM: Formatting consistency.

Data-testid updated to use double quotes for consistency.


253-259: LGTM: Button state management and loading UI.

The button correctly:

  • Disables during the drawing process to prevent double-submission
  • Shows a loading spinner for visual feedback
  • Maintains consistent width with min-w-40 to prevent layout shift

Comment thread components/GiftExchangeHeader/GiftExchangeHeader.tsx
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@shashilo
shashilo merged commit 1c0a312 into develop Nov 19, 2025
4 of 5 checks passed
@shashilo
shashilo deleted the alex/fixing-gift-generation branch November 19, 2025 19:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (1)

258-264: LGTM! Loading state implementation is solid.

The button correctly:

  • Disables during the drawing operation
  • Shows a loading spinner while processing
  • Maintains consistent width with min-w-40 to prevent layout shift

Note: There's a typo on line 274 in the AlertDialogTitle: "exchangee" should be "exchange". While this is pre-existing, consider fixing it for better UX.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 897927e and 64b0de0.

📒 Files selected for processing (1)
  • components/GiftExchangeHeader/GiftExchangeHeader.tsx (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (2)
hooks/use-toast.ts (2)
  • useToast (243-267)
  • toast (188-232)
components/LoadingSpinner/LoadingSpinner.tsx (1)
  • LoadingSpinner (3-21)
🔇 Additional comments (4)
components/GiftExchangeHeader/GiftExchangeHeader.tsx (4)

35-37: LGTM! Imports support the new loading and toast functionality.

The added imports are correctly used throughout the component for displaying loading states and toast notifications.


65-66: LGTM! State and hook initialization is correct.

The isDrawing state and toast function are properly initialized and used to manage the drawing operation's UI state.


164-169: LGTM! Error toast provides clear user feedback.

The error handling now correctly displays a toast notification to inform users when the draw operation fails, addressing the previous review feedback.


170-170: LGTM! State reset correctly placed in finally block.

The isDrawing state is now properly reset in the finally block, ensuring the UI returns to the correct state regardless of whether the operation succeeds or fails. This addresses the previous review feedback.

Comment on lines +138 to +142
toast({
variant: ToastVariants.Success,
title: '',
description: 'Please keep this browser open until our elves complete the gift drawing.',
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider using a more appropriate toast variant.

The ToastVariants.Success variant is semantically misleading for an in-progress operation. If the API call fails immediately after this toast is shown, users will see a success message followed by an error message, which can be confusing.

Consider using an info or default variant instead, or use a title like "Drawing in Progress" to clarify this is not a success confirmation but an informational message.

Apply this diff to improve clarity:

     toast({
-      variant: ToastVariants.Success,
-      title: '',
+      title: 'Drawing in Progress',
       description: 'Please keep this browser open until our elves complete the gift drawing.',
     });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In components/GiftExchangeHeader/GiftExchangeHeader.tsx around lines 138 to 142,
the toast currently uses ToastVariants.Success with an empty title for an
in-progress operation; change the variant to an informational one (e.g.,
ToastVariants.Info or the default variant) and add a clear title such as
"Drawing in progress" (or similar) so the toast communicates that the draw is
ongoing rather than a completed success; keep the same description and ensure
the toast is shown as an informational message until the API call resolves.

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