From 85d36c80a29b9a6c2148ac86cd74993613995c73 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Sat, 13 Dec 2025 07:13:21 -0600 Subject: [PATCH] fix(practice): add comprehensive logging and validation in recordSlotResult MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add detailed logging and more defensive checks to help debug production 500 errors: - Log entry point with plan ID - Wrap getSessionPlan in try-catch for better error messages - Log plan state (status, partIndex, slotIndex, parts/results arrays) - Validate slots array exists on current part - Validate results array exists - All checks provide descriptive error messages This should help identify exactly where the "Cannot read properties of undefined (reading '0')" error is coming from. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../web/src/lib/curriculum/session-planner.ts | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/apps/web/src/lib/curriculum/session-planner.ts b/apps/web/src/lib/curriculum/session-planner.ts index 2367d22f..3541ae60 100644 --- a/apps/web/src/lib/curriculum/session-planner.ts +++ b/apps/web/src/lib/curriculum/session-planner.ts @@ -500,9 +500,26 @@ export async function recordSlotResult( planId: string, result: Omit ): Promise { - const plan = await getSessionPlan(planId) + // Log entry for debugging production issues + console.log(`[recordSlotResult] Starting for plan ${planId}`) + + let plan: SessionPlan | null + try { + plan = await getSessionPlan(planId) + } catch (error) { + console.error(`[recordSlotResult] Failed to get plan ${planId}:`, error) + throw new Error( + `Failed to retrieve plan ${planId}: ${error instanceof Error ? error.message : String(error)}` + ) + } + if (!plan) throw new Error(`Plan not found: ${planId}`) + // Log plan state for debugging + console.log( + `[recordSlotResult] Plan ${planId}: status=${plan.status}, partIndex=${plan.currentPartIndex}, slotIndex=${plan.currentSlotIndex}, parts=${plan.parts ? 'defined' : 'undefined'}, results=${plan.results ? `array(${plan.results.length})` : 'undefined'}` + ) + // Defensive check: ensure parts array exists and is valid if (!plan.parts || !Array.isArray(plan.parts)) { throw new Error( @@ -510,6 +527,10 @@ export async function recordSlotResult( ) } + if (plan.parts.length === 0) { + throw new Error(`Plan ${planId} has empty parts array`) + } + if (plan.currentPartIndex < 0 || plan.currentPartIndex >= plan.parts.length) { throw new Error( `Plan ${planId} has invalid currentPartIndex: ${plan.currentPartIndex} (parts.length: ${plan.parts.length})` @@ -519,6 +540,20 @@ export async function recordSlotResult( const currentPart = plan.parts[plan.currentPartIndex] if (!currentPart) throw new Error(`Invalid part index: ${plan.currentPartIndex}`) + // Defensive check: ensure slots array exists + if (!currentPart.slots || !Array.isArray(currentPart.slots)) { + throw new Error( + `Plan ${planId} part ${plan.currentPartIndex} has invalid slots: ${typeof currentPart.slots}` + ) + } + + // Defensive check: ensure results array exists + if (!plan.results || !Array.isArray(plan.results)) { + throw new Error( + `Plan ${planId} has invalid results: ${typeof plan.results} (expected array)` + ) + } + const newResult: SlotResult = { ...result, partNumber: currentPart.partNumber,