fix(practice): add comprehensive logging and validation in recordSlotResult

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 <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-12-13 07:13:21 -06:00
parent a33e3e6d2b
commit 85d36c80a2
1 changed files with 36 additions and 1 deletions

View File

@ -500,9 +500,26 @@ export async function recordSlotResult(
planId: string,
result: Omit<SlotResult, 'timestamp' | 'partNumber'>
): Promise<SessionPlan> {
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,