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):
- APP_URL http/https mismatch
- Session driver misconfiguration
- Cookie domain mismatch
- 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:
- Double-hashing (Laravel 12+)
- Incorrect password verification
- 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
- Immediate: Check Flare + configuration (2 minutes)
- If unclear: Verify application state (3 minutes)
- If still unclear: Research specific error message (5 minutes)
- 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)