MetaDebate / docs /debugging.md
vajeeda's picture
base structure of the project formed
b6e19c7
|
Raw
History Blame Contribute Delete
4.1 kB

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

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

// 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