Spaces:
Sleeping
Sleeping
| # Debugging β Error Handling, Logging & Debug Strategy | |
| ## Purpose | |
| Read this file when an error occurs or when implementing error | |
| handling for any feature. Do not guess β follow this exactly. | |
| --- | |
| ## Core Principle | |
| **Check the specific file where the error occurred. Nothing else.** | |
| Do not scan the entire codebase. Logs must tell you: | |
| - WHERE it broke (file + function) | |
| - WHY it broke (reason) | |
| - HOW to fix it (hint) | |
| --- | |
| ## Standard Error Log Format | |
| Every error logged must follow this exact structure: | |
| [ERROR] [timestamp] [file:function] β reason β fix hint | |
| **Example:** | |
| [ERROR] [2025-01-15T10:32:00Z] [lib/supabase.ts:fetchUser] β user_id is null β check auth session before calling fetchUser | |
| --- | |
| ## Error Handler Template | |
| ### TypeScript / Next.js | |
| ```typescript | |
| function handleError(error: unknown, file: string, fn: string): void { | |
| const timestamp = new Date().toISOString() | |
| const reason = error instanceof Error ? error.message : String(error) | |
| const hint = getFixHint(reason) | |
| console.error(`[ERROR] [${timestamp}] [${file}:${fn}] β ${reason} β ${hint}`) | |
| // Write to logs/errors.log in dev | |
| if (process.env.NODE_ENV === 'development') { | |
| appendToLog('logs/errors.log', `[ERROR] [${timestamp}] [${file}:${fn}] β ${reason} β ${hint}`) | |
| } | |
| } | |
| function getFixHint(reason: string): string { | |
| if (reason.includes('null')) return 'check for null before using this value' | |
| if (reason.includes('undefined')) return 'confirm the value exists before accessing' | |
| if (reason.includes('network')) return 'check network connection and API endpoint' | |
| if (reason.includes('permission')) return 'verify Supabase RLS policies' | |
| if (reason.includes('timeout')) return 'increase timeout or check slow query' | |
| return 'check function inputs and dependencies' | |
| } | |
| ``` | |
| ### Usage in any function | |
| ```typescript | |
| // file: lib/supabase.ts | |
| async function fetchUser(userId: string) { | |
| try { | |
| if (!userId) throw new Error('user_id is null') | |
| const { data, error } = await supabase.from('users').select('*').eq('id', userId) | |
| if (error) throw error | |
| return data | |
| } catch (err) { | |
| handleError(err, 'lib/supabase.ts', 'fetchUser') | |
| return null | |
| } | |
| } | |
| ``` | |
| --- | |
| ## Logging Levels | |
| | Level | When to Use | | |
| |-------|------------| | |
| | `[ERROR]` | Something broke, feature cannot continue | | |
| | `[WARN]` | Something unexpected but recoverable | | |
| | `[INFO]` | Key state changes, successful operations | | |
| | `[DEBUG]` | Verbose, dev-only, remove before production | | |
| --- | |
| ## Debug Steps β When Something Breaks | |
| 1. Read `logs/errors.log` β find the exact `[file:function]` | |
| 2. Open only that file | |
| 3. Check the function mentioned in the log | |
| 4. Verify inputs to that function | |
| 5. Check for null/undefined before the failure point | |
| 6. Fix inline, do not refactor adjacent code | |
| 7. Re-run the specific test for that function only | |
| **Do not open other files unless the log explicitly points to them.** | |
| --- | |
| ## Supabase Specific Errors | |
| | Error | Likely Cause | Fix | | |
| |-------|-------------|-----| | |
| | `permission denied` | RLS policy blocking query | Check policy in Supabase dashboard β Auth β Policies | | |
| | `relation does not exist` | Migration not applied | Run `supabase db push` | | |
| | `violates foreign key` | Referenced row missing | Insert parent record first | | |
| | `JWT expired` | Auth token stale | Refresh session with `supabase.auth.refreshSession()` | | |
| | `null value in column` | Missing required field | Validate inputs before insert | | |
| --- | |
| ## Edge Case Checklist | |
| Before shipping any function, verify: | |
| - [ ] What happens if input is null or undefined? | |
| - [ ] What happens if the DB returns empty array? | |
| - [ ] What happens if the API call times out? | |
| - [ ] What happens if the user is not authenticated? | |
| - [ ] What happens if this runs twice simultaneously? | |
| --- | |
| ## What NOT to Do | |
| - Do not use `console.log` for errors β use `console.error` with the format above | |
| - Do not catch an error and do nothing with it | |
| - Do not log sensitive data (passwords, tokens, PII) | |
| - Do not open unrelated files to debug an error | |
| - Do not refactor while debugging β fix first, refactor later |