Skip to content

Fixing infinite loop->if the RPC check_team_code_exists throws an exception - #156

Closed
aniket866 wants to merge 1 commit into
AOSSIE-Org:mainfrom
aniket866:fixing-infinite-loop
Closed

aniket866 wants to merge 1 commit into
AOSSIE-Org:mainfrom
aniket866:fixing-infinite-loop

Conversation

@aniket866

@aniket866 aniket866 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

Where: SupabaseService.createTeam

Issue: The do-while loop tries 10 times to generate a unique ID. If the RPC check_team_code_exists throws an exception (e.g. network error), it counts as a failed attempt. 10 network errors = "Failed to create team".

Fix: Distinguish between "Code exists" (retry) and "Network Error" (throw immediately or retry with backoff).

@SharkyBytes Please review Closes #155

Summary by CodeRabbit

Bug Fixes

  • Improved team code generation reliability with explicit attempt limits to prevent generation failures
  • Enhanced error messages for network connection issues during signup
  • Consistent error handling across all signup workflows

@coderabbitai

coderabbitai Bot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The changes refactor team code generation across multiple authentication flows by replacing do-while loops with bounded while loops (10-attempt limit), adding explicit error handling to distinguish between collision detection (retry) and network failures (fail-fast), and ensuring consistent error reporting across createTeam, createTeamWithGoogle, and OTP-based signup verification paths.

Changes

Cohort / File(s) Summary
Team Code Generation & Validation
lib/services/supabase_service.dart
Replaced do-while loops with while loops constrained to 10 attempts. Updated uniqueness check semantics to distinguish collision (RPC returns true) from unique code (returns false). Modified RPC/network error handling to fail-fast with connection-specific messages instead of retrying. Added explicit post-loop guards to throw errors if unique code generation fails. Applied pattern consistently across createTeam, createTeamWithGoogle, and OTP signup verification flows.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Hopping through the code with glee,
Loop bounds now set to 10, you see!
Network errors? Fail-fast and clear,
No infinite loops to fear!
Team codes unique, logic sound,
Better error handling found!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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 focus of the PR: fixing an infinite loop issue triggered by RPC exceptions in check_team_code_exists, which is the core problem being addressed.
Linked Issues check ✅ Passed The PR implementation directly addresses issue #155's requirement to differentiate RPC exceptions from code-exists responses, replacing do-while loops with explicit attempt limits and fast-fail error handling.
Out of Scope Changes check ✅ Passed All changes consistently apply the same pattern across createTeam, createTeamWithGoogle, and OTP-based flows to fix the RPC exception handling issue, with no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
lib/services/ai_service.dart (1)

380-380: ⚠️ Potential issue | 🟡 Minor

Avoid logging the full request body (contains API key in URL and potentially sensitive user messages).

Line 380 logs the entire requestBody (which includes chat history with user messages) and line 527 does the same. In production, this could leak PII or sensitive conversation content into logs. Consider gating these behind a kDebugMode check or removing them.

🤖 Fix all issues with AI agents
In `@lib/services/supabase_service.dart`:
- Around line 349-354: The outer catch in the createTeam and
createTeamWithGoogle flows swallows the inner, more specific exception message
(e.g., the Exception thrown in the team-code uniqueness check) and always
returns a generic 'Failed to create team' error; update the outer catch in the
methods (look for createTeam and createTeamWithGoogle in supabase_service.dart)
to preserve and propagate the original error message (e.g., include e.toString()
or inspect the exception type/message and use it in the thrown/returned
Exception) so connection/RPC errors like 'Unable to verify team code uniqueness.
Please check your connection.' are surfaced to the caller instead of being
overwritten by the generic message.
- Around line 709-739: The code block starting at the unique-team-id generation
is orphaned—add a proper async method declaration above it: declare
Future<Map<String, dynamic>> createTeamWithGoogle({ required String teamName,
required String ownerId, /* add any other parameters referenced in the body */
}) async { and then ensure the existing body (including the while loop, RPC
calls like _client.rpc, try/catch blocks) is inside the method, with matching
braces and a final return statement returning a Map<String, dynamic> (or the
expected result object) and appropriate error handling; reference
createTeamWithGoogle, generateTeamId, _client.rpc, and the isUnique/attempts
variables to locate where to insert the signature and close the method.
🧹 Nitpick comments (4)
lib/services/supabase_service.dart (2)

924-952: Consistent application of the fix — looks good.

The OTP signup_create flow applies the same pattern: collision → increment + continue, RPC error → throw, post-loop guard. This is consistent with the createTeam fix.

One minor note: the error messages differ slightly across the three instances ('Unable to verify team code uniqueness. Please check your connection.' in createTeam, 'Unable to verify team code uniqueness. Please check your connection.' in createTeamWithGoogle, and the shorter 'Unable to verify team code uniqueness.' here at line 946). Consider using a consistent message for all three for uniform UX.


327-360: Consider extracting the unique team code generation into a shared helper method.

The same loop pattern (generate code → check via RPC → retry on collision, fail fast on error, guard post-loop) is duplicated across createTeam, createTeamWithGoogle, and the OTP signup_create flow. Extracting this into a single Future<String> _generateUniqueTeamCode() method would reduce duplication and ensure future fixes apply uniformly.

Also applies to: 709-739, 924-952

lib/services/ai_service.dart (2)

392-434: Good defensive improvement wrapping JSON decoding in try-catch.

The logic correctly prioritizes function calls over text parts and falls back gracefully. One minor robustness concern: line 397 casts responseData['candidates'] directly to List<dynamic>. If the key is absent or null (e.g., a content-filtered response), the cast throws, and the catch block returns "invalid response from AI server" — which is slightly misleading vs. the more apt "No response generated" at line 426. A null-check before the cast would let you distinguish the two cases.

Suggested improvement
-          final candidates = responseData['candidates'] as List<dynamic>;
-          if (candidates.isNotEmpty) {
+          final candidates = responseData['candidates'] as List<dynamic>?;
+          if (candidates != null && candidates.isNotEmpty) {

538-552: handleToolResponse lacks the same try-catch hardening applied to generateChatResponse.

Lines 539–543 perform jsonDecode and cast candidates without try-catch protection, while the parallel code path in generateChatResponse (lines 392–434) was just hardened. A malformed follow-up response here would crash instead of returning a safe fallback. Consider applying the same pattern for consistency.

Comment thread lib/services/supabase_service.dart
Comment on lines +709 to +739
// Generate a unique team ID
String teamId = '';
bool isUnique = false;
int attempts = 0;

do {
while (!isUnique && attempts < 10) {
teamId = generateTeamId();
attempts++;

try {
final response = await _client.rpc(
'check_team_code_exists',
params: {'code': teamId},
);

isUnique = response == false;
if (response == true) {
attempts++;
continue;
}

isUnique = true;
} catch (e) {
debugPrint('Error checking team code: $e');
// If RPC consistently fails, throw error instead of risking duplicates
if (attempts >= 3) {
throw Exception(
'Unable to verify team code uniqueness. Please try again.');
}
throw Exception(
'Unable to verify team code uniqueness. Please check your connection.');
}
} while (!isUnique && attempts < 10);
}

if (!isUnique) {
throw Exception(
'Failed to generate a unique team code after multiple attempts. Please try again.');
}

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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether the createTeamWithGoogle method signature exists in the file
echo "=== Searching for createTeamWithGoogle declaration ==="
rg -n 'createTeamWithGoogle' lib/services/supabase_service.dart

echo ""
echo "=== Lines 700-720 of supabase_service.dart ==="
sed -n '700,720p' lib/services/supabase_service.dart

Repository: AOSSIE-Org/Ell-ena

Length of output: 688


🏁 Script executed:

#!/bin/bash
echo "=== Lines 685-750 to see full context ==="
sed -n '685,750p' lib/services/supabase_service.dart

echo ""
echo "=== Check file structure around method definitions ==="
rg -n 'Future.*createTeam|Future.*joinTeam|^\s*Future' lib/services/supabase_service.dart | head -20

Repository: AOSSIE-Org/Ell-ena

Length of output: 3113


Critical: createTeamWithGoogle method signature is missing.

The code body starting at line 709 (unique team ID generation) lacks a method declaration. Line 708 contains only a comment, followed immediately by variable declarations with no return type, method name, parameters, or opening brace. This code is orphaned and will not compile.

The file jumps directly from the closing of joinTeamWithGoogle (line 706) to the uncommented code body at line 709. A search of the file confirms no createTeamWithGoogle method declaration exists anywhere.

You need to add the method signature above line 709, likely:

Future<Map<String, dynamic>> createTeamWithGoogle({
  required String teamName,
  // ... other parameters
}) async {
  try {
🤖 Prompt for AI Agents
In `@lib/services/supabase_service.dart` around lines 709 - 739, The code block
starting at the unique-team-id generation is orphaned—add a proper async method
declaration above it: declare Future<Map<String, dynamic>>
createTeamWithGoogle({ required String teamName, required String ownerId, /* add
any other parameters referenced in the body */ }) async { and then ensure the
existing body (including the while loop, RPC calls like _client.rpc, try/catch
blocks) is inside the method, with matching braces and a final return statement
returning a Map<String, dynamic> (or the expected result object) and appropriate
error handling; reference createTeamWithGoogle, generateTeamId, _client.rpc, and
the isUnique/attempts variables to locate where to insert the signature and
close the method.

@aniket866
aniket866 force-pushed the fixing-infinite-loop branch from 150e724 to 4675760 Compare February 7, 2026 19:30

@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.

Caution

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

⚠️ Outside diff range comments (1)
lib/services/supabase_service.dart (1)

327-355: 🛠️ Refactor suggestion | 🟠 Major

Extract the team-code generation + uniqueness check into a shared helper.

The bounded-retry + RPC-check logic is now duplicated verbatim in createTeam, createTeamWithGoogle, and the verifyOTP signup path. A single helper would eliminate the three copies and make future changes (e.g., adding backoff) a one-line fix.

Example helper
/// Generates a unique team code, retrying up to [maxAttempts] times.
/// Throws on RPC/network errors or if no unique code is found.
Future<String> _generateUniqueTeamCode({int maxAttempts = 10}) async {
  for (int attempt = 0; attempt < maxAttempts; attempt++) {
    final code = generateTeamId();
    try {
      final response = await _client.rpc(
        'check_team_code_exists',
        params: {'code': code},
      );
      if (response == true) continue; // collision, retry
      if (response == false) return code; // unique
      // unexpected response
      debugPrint('Unexpected RPC response: $response');
    } catch (e) {
      debugPrint('Error checking team code: $e');
      throw Exception(
        'Unable to verify team code uniqueness. Please check your connection.',
      );
    }
  }
  throw Exception(
    'Failed to generate a unique team code after multiple attempts.',
  );
}
🧹 Nitpick comments (1)
lib/services/supabase_service.dart (1)

327-360: The loop logic correctly addresses the original infinite-loop bug.

The bounded while loop with fail-fast on RPC errors and the post-loop guard are sound improvements. Good work.

One subtlety: if the RPC returns null (e.g., unexpected schema change or edge case), the response == true check passes through to isUnique = true, treating an ambiguous result as "unique." Consider adding an explicit check for response == false before accepting uniqueness:

Suggested defensive check
           if (response == true) {
             attempts++;
             continue;
           }
-          
-          // If response is false, the code is unique
-          isUnique = true;
+
+          if (response == false) {
+            isUnique = true;
+          } else {
+            // Unexpected response from RPC
+            debugPrint('Unexpected RPC response: $response');
+            attempts++;
+          }

@aniket866 aniket866 closed this Feb 7, 2026
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.

if the RPC check_team_code_exists throws an exception (e.g. network error), it counts as a failed attempt->Infinite loop

1 participant