Error Handling

Systematic approaches to identify, debug, and resolve errors efficiently without guessing.


Prime Directive

RESEARCH BEFORE DECLARING FAILURE

NEVER guess at solutions when stakes are high

Systematic debugging is FASTER than guessing, especially when customers are waiting.


Production Error Protocol

Use: ~/.claude/PRODUCTION_ERROR_CHECKLIST.md

Step-by-Step Procedure

1. Check Flare FIRST (Always, no exceptions)

~/.claude/check_flare_errors.sh

Why: Complete stack trace, user context, environment data in seconds

2. Check Configuration (Before touching code)

# APP_URL mismatch is #1 cause
ssh server "cat .env | grep APP_URL"
ssh server "cd /path && php artisan tinker --execute='echo config(\"app.url\")'"

# Check environment
ssh server "cat .env | grep APP_ENV"

# Check database
ssh server "cat .env | grep DB_"

# Check cache
ssh server "cat .env | grep CACHE_"

3. Verify Application State

# Database connection
ssh server "cd /path && php artisan tinker --execute='DB::connection()->getPdo()'"

# Clear caches
ssh server "cd /path && php artisan config:clear && php artisan cache:clear"

# Check logs
ssh server "tail -100 /path/storage/logs/laravel.log"

4. THEN Research and Fix

Only after configuration is verified should you dive into code.


Common Laravel Errors

419 CSRF Token Mismatch

Root Causes (in order of frequency):

  1. APP_URL http/https mismatch
  2. Session driver misconfiguration
  3. Cookie domain mismatch
  4. Expired session

Debug Steps:

# Check APP_URL
ssh server "cat .env | grep APP_URL"
# Should match actual URL (https://domain.com not http or localhost)

# Check session config
ssh server "cd /path && php artisan tinker --execute='print_r(config(\"session\"))'"

# Check session storage
ssh server "ls -la /path/storage/framework/sessions/"

# Clear sessions
ssh server "cd /path && php artisan session:flush"

Fix:

# Update .env
APP_URL=https://actual-domain.com

# Clear caches
ssh server "cd /path && php artisan config:clear"

Password Authentication Failures

Root Causes:

  1. Double-hashing (Laravel 12+)
  2. Incorrect password verification
  3. Password reset not working

Laravel 12 Double-Hash Issue:

// WRONG - double hash due to 'hashed' cast
$user->password = bcrypt('password');
$user->save();

// CORRECT
$user->password = Hash::make('password');
$user->saveQuietly(); // Bypass cast

// VERIFY
password_verify('password', $user->password); // Must be true

500 Internal Server Error

Debug Steps:

# Check Flare for stack trace
~/.claude/check_flare_errors.sh

# Check Laravel logs
ssh server "tail -100 /path/storage/logs/laravel.log"

# Check PHP logs
ssh server "tail -100 /var/log/php8.2-fpm.log"

# Check web server logs
ssh server "tail -100 /var/log/nginx/error.log"

Database Connection Errors

Debug Steps:

# Verify credentials
ssh server "cat .env | grep DB_"

# Test connection
ssh server "cd /path && php artisan tinker --execute='DB::connection()->getPdo()'"

# Check database exists
ssh server "mysql -u user -p -e 'SHOW DATABASES'"

# Check permissions
ssh server "mysql -u user -p -e 'SHOW GRANTS'"

Error Escalation

When Customer is Waiting

Time wasted = 0 tolerance

  1. Immediate: Check Flare + configuration (2 minutes)
  2. If unclear: Verify application state (3 minutes)
  3. If still unclear: Research specific error message (5 minutes)
  4. Total time before asking: 10 minutes maximum

NEVER spend 30+ minutes guessing

Critical Error Indicators

Immediate escalation required:

  • Payment processing failures
  • Authentication completely broken
  • Data loss or corruption
  • Security vulnerabilities
  • Customer-facing errors affecting all users

Debugging Workflow

1. Reproduce the Error

Required:

  • Exact steps to reproduce
  • Expected behavior
  • Actual behavior
  • Screenshots/screen recording

Test Reproduction:

# Try to reproduce locally
# If can't reproduce locally, test on staging
# If can't reproduce on staging, investigate production-specific config

2. Isolate the Issue

Narrow down:

  • Which component (frontend, backend, database, cache, queue)?
  • Which specific function/method?
  • What triggers it (user action, cron, event)?

Tools:

  • Flare for stack traces
  • Browser DevTools for frontend
  • Laravel logs for backend
  • Database query logs for DB

3. Identify Root Cause

Common root causes:

  • Configuration mismatch
  • Missing environment variable
  • Cache serving stale data
  • Database migration not run
  • File permissions
  • Third-party API failure

4. Fix and Verify

Fix:

  • Make minimal change to resolve root cause
  • Don't fix symptoms, fix the cause

Verify:

  • Test reproduction steps
  • No new errors in Flare
  • Monitor for 5-10 minutes
  • Take screenshot evidence

Error Prevention

Configuration Checklist

Before deploying:

  • APP_URL matches production URL
  • APP_ENV set to "production"
  • APP_DEBUG set to false
  • Database credentials correct
  • Cache driver configured
  • Queue driver configured
  • Mail driver configured

Testing Checklist

Before declaring complete:

  • Happy path tested
  • Error scenarios tested
  • Edge cases tested
  • Browser console checked
  • Flare checked
  • No regressions introduced

Monitoring Checklist

After deployment:

  • Check Flare every 5 minutes for 30 minutes
  • Test critical user paths
  • Monitor server resources
  • Check background job queues
  • Verify scheduled tasks running

Error Types & Solutions

Configuration Errors

Symptom: Environment-specific failures Solution: Verify .env, check loaded config with tinker Prevention: Use .env.example, document all required variables

Cache Errors

Symptom: Stale data, old config values Solution: php artisan config:clear && php artisan cache:clear Prevention: Clear cache after config changes, use cache tags

Permission Errors

Symptom: 500 errors, can't write files Solution: chmod 755 directories, chmod 644 files, chown www-data Prevention: Proper deployment script, correct user/group

Database Errors

Symptom: Migration failures, query errors Solution: Run migrations, check relationships, verify constraints Prevention: Test migrations on staging first, use database transactions


Critical Lessons

From Operational Log

Lesson #1: APP_URL http/https mismatch is #1 cause of production issues

  • Always check configuration FIRST
  • Don't assume .env matches expectations

Lesson #2: Laravel 12 password hashing changed

  • 'password' => 'hashed' cast auto-hashes
  • Using bcrypt() then save() = double hash
  • Use Hash::make() with saveQuietly()

Lesson #3: Flare provides answers in seconds

  • Full stack trace with context
  • Don't waste time guessing
  • Check Flare BEFORE diving into code

Lesson #4: Never claim "fixed" without verification

  • Test in actual browser
  • Take screenshots
  • Monitor Flare
  • Wait 5-10 minutes

Troubleshooting Tools

Laravel-Specific

# Clear all caches
php artisan optimize:clear

# Regenerate autoloader
composer dump-autoload

# Check route list
php artisan route:list

# Interactive console
php artisan tinker

# View configuration
php artisan config:show

Server-Level

# Check PHP version
php -v

# Check PHP modules
php -m

# Check process status
ps aux | grep php-fpm

# Check error logs
tail -f /var/log/php8.2-fpm.log
tail -f /var/log/nginx/error.log

Status: Production-tested error resolution protocols Last Major Update: After 419 CSRF debugging incident (2025-10-05)

Was this page helpful?