chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,557 @@
|
||||
# Database Error Patterns
|
||||
|
||||
Common database errors across PostgreSQL, MySQL, MongoDB, Redis, and SQLite.
|
||||
|
||||
## Connection Errors
|
||||
|
||||
### Connection Refused
|
||||
|
||||
```
|
||||
Error: connect ECONNREFUSED 127.0.0.1:5432
|
||||
FATAL: connection refused
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Database server not running
|
||||
2. Wrong host/port
|
||||
3. Firewall blocking connection
|
||||
4. Max connections reached
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check if database is running
|
||||
# PostgreSQL
|
||||
pg_isready -h localhost -p 5432
|
||||
|
||||
# MySQL
|
||||
mysqladmin ping -h localhost
|
||||
|
||||
# Check port
|
||||
lsof -i :5432
|
||||
netstat -an | grep 5432
|
||||
|
||||
# Check process
|
||||
ps aux | grep postgres
|
||||
ps aux | grep mysql
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Start database
|
||||
# PostgreSQL
|
||||
brew services start postgresql # macOS
|
||||
sudo systemctl start postgresql # Linux
|
||||
|
||||
# MySQL
|
||||
brew services start mysql # macOS
|
||||
sudo systemctl start mysql # Linux
|
||||
|
||||
# Docker
|
||||
docker start postgres_container
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Authentication Failed
|
||||
|
||||
```
|
||||
FATAL: password authentication failed for user "username"
|
||||
Access denied for user 'root'@'localhost'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Wrong password
|
||||
2. User doesn't exist
|
||||
3. Wrong authentication method
|
||||
4. User lacks permissions
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# PostgreSQL - reset password
|
||||
sudo -u postgres psql
|
||||
ALTER USER username PASSWORD 'newpassword';
|
||||
|
||||
# MySQL - reset password
|
||||
mysql -u root
|
||||
ALTER USER 'username'@'localhost' IDENTIFIED BY 'newpassword';
|
||||
FLUSH PRIVILEGES;
|
||||
|
||||
# Check pg_hba.conf for auth method (PostgreSQL)
|
||||
# Change 'peer' to 'md5' or 'scram-sha-256' for password auth
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Database Does Not Exist
|
||||
|
||||
```
|
||||
FATAL: database "mydb" does not exist
|
||||
Unknown database 'mydb'
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# PostgreSQL
|
||||
createdb mydb
|
||||
# Or in psql:
|
||||
CREATE DATABASE mydb;
|
||||
|
||||
# MySQL
|
||||
mysql -u root -p -e "CREATE DATABASE mydb;"
|
||||
|
||||
# Check existing databases
|
||||
psql -l # PostgreSQL
|
||||
mysql -e "SHOW DATABASES;" # MySQL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Connection Timeout
|
||||
|
||||
```
|
||||
Error: Connection timed out
|
||||
FATAL: connection timeout expired
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Network latency
|
||||
2. Database overloaded
|
||||
3. Firewall issues
|
||||
4. DNS resolution slow
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Increase connection timeout
|
||||
// Node.js pg
|
||||
const pool = new Pool({
|
||||
connectionTimeoutMillis: 10000, // 10 seconds
|
||||
})
|
||||
|
||||
// Prisma
|
||||
datasource db {
|
||||
url = "postgresql://...?connect_timeout=10"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Too Many Connections
|
||||
|
||||
```
|
||||
FATAL: too many connections for role "postgres"
|
||||
ERROR 1040 (HY000): Too many connections
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Connection leaks (not closing connections)
|
||||
2. Pool size too large
|
||||
3. Max connections too low
|
||||
|
||||
**Diagnosis**:
|
||||
```sql
|
||||
-- PostgreSQL
|
||||
SELECT count(*) FROM pg_stat_activity;
|
||||
SELECT * FROM pg_stat_activity WHERE state = 'idle';
|
||||
|
||||
-- MySQL
|
||||
SHOW PROCESSLIST;
|
||||
SHOW STATUS LIKE 'Threads_connected';
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- PostgreSQL - increase max connections
|
||||
ALTER SYSTEM SET max_connections = 200;
|
||||
-- Requires restart
|
||||
|
||||
-- MySQL
|
||||
SET GLOBAL max_connections = 200;
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Use connection pooling properly
|
||||
const pool = new Pool({
|
||||
max: 20, // Pool size
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
})
|
||||
|
||||
// Always release connections
|
||||
const client = await pool.connect()
|
||||
try {
|
||||
await client.query('...')
|
||||
} finally {
|
||||
client.release() // Important!
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Query Errors
|
||||
|
||||
### Syntax Error
|
||||
|
||||
```
|
||||
ERROR: syntax error at or near "FROM"
|
||||
You have an error in your SQL syntax
|
||||
```
|
||||
|
||||
**Common Causes**:
|
||||
1. Missing quotes around strings
|
||||
2. Reserved word used as identifier
|
||||
3. Missing comma in list
|
||||
4. Wrong function name
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- Quote reserved words
|
||||
SELECT "order", "user" FROM "table"; -- PostgreSQL
|
||||
SELECT `order`, `user` FROM `table`; -- MySQL
|
||||
|
||||
-- Check string quoting
|
||||
WHERE name = 'John' -- Correct
|
||||
WHERE name = "John" -- Wrong in PostgreSQL (double quotes = identifier)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Column Does Not Exist
|
||||
|
||||
```
|
||||
ERROR: column "username" does not exist
|
||||
Unknown column 'username' in 'field list'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Typo in column name
|
||||
2. Case sensitivity issue
|
||||
3. Column not in table
|
||||
4. Wrong table alias
|
||||
|
||||
**Diagnosis**:
|
||||
```sql
|
||||
-- PostgreSQL
|
||||
\d table_name
|
||||
|
||||
-- MySQL
|
||||
DESCRIBE table_name;
|
||||
SHOW COLUMNS FROM table_name;
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- PostgreSQL is case-sensitive with quoted identifiers
|
||||
SELECT "Username" FROM users; -- Looks for exact "Username"
|
||||
SELECT username FROM users; -- Looks for lowercase
|
||||
|
||||
-- Check actual columns
|
||||
SELECT column_name FROM information_schema.columns
|
||||
WHERE table_name = 'users';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Relation/Table Does Not Exist
|
||||
|
||||
```
|
||||
ERROR: relation "users" does not exist
|
||||
Table 'database.users' doesn't exist
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Table not created
|
||||
2. Wrong schema/database
|
||||
3. Typo in table name
|
||||
4. Migrations not run
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- Check existing tables
|
||||
-- PostgreSQL
|
||||
\dt
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_schema = 'public';
|
||||
|
||||
-- MySQL
|
||||
SHOW TABLES;
|
||||
|
||||
-- Check current schema
|
||||
SELECT current_schema(); -- PostgreSQL
|
||||
SELECT DATABASE(); -- MySQL
|
||||
```
|
||||
|
||||
```bash
|
||||
# Run migrations
|
||||
npx prisma migrate dev
|
||||
npx sequelize-cli db:migrate
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Constraint Violation
|
||||
|
||||
#### Unique Constraint
|
||||
|
||||
```
|
||||
ERROR: duplicate key value violates unique constraint
|
||||
Duplicate entry 'value' for key 'PRIMARY'
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- Check for existing value
|
||||
SELECT * FROM users WHERE email = 'test@example.com';
|
||||
|
||||
-- Upsert instead of insert
|
||||
-- PostgreSQL
|
||||
INSERT INTO users (email, name) VALUES ('test@example.com', 'Test')
|
||||
ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name;
|
||||
|
||||
-- MySQL (8.0.20+)
|
||||
INSERT INTO users (email, name) VALUES ('test@example.com', 'Test') AS new_values
|
||||
ON DUPLICATE KEY UPDATE name = new_values.name;
|
||||
```
|
||||
|
||||
#### Foreign Key Constraint
|
||||
|
||||
```
|
||||
ERROR: insert or update violates foreign key constraint
|
||||
Cannot add or update a child row: a foreign key constraint fails
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- Check if referenced record exists
|
||||
SELECT * FROM parent_table WHERE id = 123;
|
||||
|
||||
-- Insert parent first, then child
|
||||
INSERT INTO parent_table (id) VALUES (123);
|
||||
INSERT INTO child_table (parent_id) VALUES (123);
|
||||
|
||||
-- Or use CASCADE
|
||||
ALTER TABLE child_table
|
||||
ADD CONSTRAINT fk_parent
|
||||
FOREIGN KEY (parent_id) REFERENCES parent_table(id)
|
||||
ON DELETE CASCADE;
|
||||
```
|
||||
|
||||
#### Not Null Constraint
|
||||
|
||||
```
|
||||
ERROR: null value in column "email" violates not-null constraint
|
||||
Column 'email' cannot be null
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- Provide value
|
||||
INSERT INTO users (name, email) VALUES ('Test', 'test@example.com');
|
||||
|
||||
-- Or add default
|
||||
ALTER TABLE users ALTER COLUMN email SET DEFAULT 'default@example.com';
|
||||
|
||||
-- Or make nullable
|
||||
ALTER TABLE users ALTER COLUMN email DROP NOT NULL; -- PostgreSQL
|
||||
ALTER TABLE users MODIFY email VARCHAR(255) NULL; -- MySQL
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Deadlock
|
||||
|
||||
```
|
||||
ERROR: deadlock detected
|
||||
Deadlock found when trying to get lock
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Transactions waiting on each other
|
||||
2. Lock ordering inconsistent
|
||||
3. Long-running transactions
|
||||
|
||||
**Solutions**:
|
||||
```sql
|
||||
-- Always access tables in same order across transactions
|
||||
|
||||
-- Keep transactions short
|
||||
BEGIN;
|
||||
-- Quick operations only
|
||||
COMMIT;
|
||||
|
||||
-- Use appropriate isolation level
|
||||
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Helper function
|
||||
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
// Retry on deadlock
|
||||
async function withRetry(fn, maxRetries = 3) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
return await fn()
|
||||
} catch (error) {
|
||||
if (error.code === '40P01' && i < maxRetries - 1) { // Deadlock
|
||||
await sleep(100 * (i + 1))
|
||||
continue
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MongoDB Errors
|
||||
|
||||
### MongoServerSelectionError
|
||||
|
||||
```
|
||||
MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Start MongoDB
|
||||
brew services start mongodb-community # macOS
|
||||
sudo systemctl start mongod # Linux
|
||||
|
||||
# Check status
|
||||
mongosh --eval "db.adminCommand('ping')"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### MongoError: E11000 duplicate key error
|
||||
|
||||
```
|
||||
MongoError: E11000 duplicate key error collection: db.users index: email_1
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Upsert
|
||||
await User.findOneAndUpdate(
|
||||
{ email: 'test@example.com' },
|
||||
{ $set: { name: 'Test' } },
|
||||
{ upsert: true }
|
||||
)
|
||||
|
||||
// Or handle error
|
||||
try {
|
||||
await user.save()
|
||||
} catch (error) {
|
||||
if (error.code === 11000) {
|
||||
// Handle duplicate
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### MongooseError: Operation timed out
|
||||
|
||||
```
|
||||
MongooseError: Operation `users.find()` buffering timed out after 10000ms
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Not connected to database
|
||||
2. Connection dropped
|
||||
3. Query too slow
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Wait for connection
|
||||
await mongoose.connect(uri)
|
||||
console.log('Connected to MongoDB')
|
||||
|
||||
// Then start server
|
||||
app.listen(3000)
|
||||
|
||||
// Add connection events
|
||||
mongoose.connection.on('error', console.error)
|
||||
mongoose.connection.on('disconnected', () => {
|
||||
console.log('MongoDB disconnected')
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Redis Errors
|
||||
|
||||
### ECONNREFUSED
|
||||
|
||||
```
|
||||
Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Start Redis
|
||||
brew services start redis # macOS
|
||||
sudo systemctl start redis # Linux
|
||||
|
||||
# Test connection
|
||||
redis-cli ping
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### WRONGTYPE
|
||||
|
||||
```
|
||||
WRONGTYPE Operation against a key holding the wrong kind of value
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Key exists with different type
|
||||
2. Using wrong command for data type
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check key type
|
||||
TYPE mykey
|
||||
|
||||
# Delete and recreate with correct type
|
||||
DEL mykey
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### OOM command not allowed
|
||||
|
||||
```
|
||||
OOM command not allowed when used memory > 'maxmemory'
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Increase max memory
|
||||
redis-cli CONFIG SET maxmemory 2gb
|
||||
|
||||
# Set eviction policy
|
||||
redis-cli CONFIG SET maxmemory-policy allkeys-lru
|
||||
|
||||
# In redis.conf
|
||||
maxmemory 2gb
|
||||
maxmemory-policy allkeys-lru
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Database | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| Connection refused | All | Start database service |
|
||||
| Auth failed | All | Check credentials, reset password |
|
||||
| DB doesn't exist | All | Create database |
|
||||
| Too many connections | All | Use connection pooling |
|
||||
| Unique constraint | All | Use upsert |
|
||||
| Foreign key violation | All | Insert parent first |
|
||||
| Deadlock | All | Retry with backoff |
|
||||
| E11000 duplicate | MongoDB | Use findOneAndUpdate with upsert |
|
||||
| WRONGTYPE | Redis | Check key type with TYPE |
|
||||
@@ -0,0 +1,566 @@
|
||||
# Docker Error Patterns
|
||||
|
||||
Common Docker and container errors with diagnosis and solutions.
|
||||
|
||||
## Build Errors
|
||||
|
||||
### Dockerfile parse error
|
||||
|
||||
```
|
||||
failed to solve: dockerfile parse error
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Syntax error in Dockerfile
|
||||
2. Invalid instruction
|
||||
3. Missing required argument
|
||||
|
||||
**Common Issues**:
|
||||
```dockerfile
|
||||
# Wrong - missing argument
|
||||
FROM
|
||||
|
||||
# Correct
|
||||
FROM node:18-alpine
|
||||
|
||||
# Wrong - instruction case (older Docker)
|
||||
from node:18
|
||||
run npm install
|
||||
|
||||
# Correct - uppercase instructions
|
||||
FROM node:18
|
||||
RUN npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### COPY failed: file not found
|
||||
|
||||
```
|
||||
COPY failed: file not found in build context
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. File doesn't exist
|
||||
2. File is in .dockerignore
|
||||
3. Wrong path (relative to build context)
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check build context
|
||||
ls -la
|
||||
|
||||
# Check .dockerignore
|
||||
cat .dockerignore
|
||||
|
||||
# Build with verbose output
|
||||
docker build --progress=plain .
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```dockerfile
|
||||
# Path is relative to build context, not Dockerfile
|
||||
# If Dockerfile is in root, and file is in root:
|
||||
COPY package.json .
|
||||
|
||||
# If building from parent directory:
|
||||
# docker build -f app/Dockerfile .
|
||||
COPY app/package.json .
|
||||
|
||||
# Check file exists in build context
|
||||
# (not in .dockerignore)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### RUN command failed
|
||||
|
||||
```
|
||||
ERROR: failed to solve: process "/bin/sh -c npm install" did not complete successfully
|
||||
```
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Build with no cache to see full output
|
||||
docker build --no-cache --progress=plain .
|
||||
```
|
||||
|
||||
**Common Fixes**:
|
||||
```dockerfile
|
||||
# Add build dependencies
|
||||
FROM node:18-alpine
|
||||
RUN apk add --no-cache python3 make g++ # For native modules
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
# Use specific npm version
|
||||
RUN npm install -g npm@10
|
||||
RUN npm ci
|
||||
|
||||
# Clear npm cache if issues
|
||||
RUN npm cache clean --force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cannot connect to Docker daemon
|
||||
|
||||
```
|
||||
Cannot connect to the Docker daemon at unix:///var/run/docker.sock
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Docker not running
|
||||
2. Permission denied
|
||||
3. Wrong socket path
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Start Docker
|
||||
# macOS - start Docker Desktop
|
||||
|
||||
# Linux
|
||||
sudo systemctl start docker
|
||||
|
||||
# Check status
|
||||
docker info
|
||||
|
||||
# Permission issue - add user to docker group
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker # Or logout/login
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### No space left on device
|
||||
|
||||
```
|
||||
no space left on device
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Remove unused resources
|
||||
docker system prune -a
|
||||
|
||||
# Remove all unused images
|
||||
docker image prune -a
|
||||
|
||||
# Remove all stopped containers
|
||||
docker container prune
|
||||
|
||||
# Remove unused volumes
|
||||
docker volume prune
|
||||
|
||||
# Check disk usage
|
||||
docker system df
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Runtime Errors
|
||||
|
||||
### Container exits immediately
|
||||
|
||||
```
|
||||
Container exited with code 0/1
|
||||
```
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check logs
|
||||
docker logs container_name
|
||||
|
||||
# Run interactively
|
||||
docker run -it image_name /bin/sh
|
||||
|
||||
# Check entrypoint
|
||||
docker inspect image_name | grep -A5 Entrypoint
|
||||
```
|
||||
|
||||
**Common Causes**:
|
||||
|
||||
1. **No foreground process**
|
||||
```dockerfile
|
||||
# Wrong - runs in background
|
||||
CMD ["node", "server.js", "&"]
|
||||
|
||||
# Correct - runs in foreground
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
2. **Script exits**
|
||||
```dockerfile
|
||||
# Keep container running
|
||||
CMD ["tail", "-f", "/dev/null"]
|
||||
```
|
||||
|
||||
3. **Error on startup**
|
||||
```bash
|
||||
# Check exit code
|
||||
docker inspect container_name --format='{{.State.ExitCode}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Port already in use
|
||||
|
||||
```
|
||||
Error: listen EADDRINUSE: address already in use :::3000
|
||||
Bind for 0.0.0.0:3000 failed: port is already allocated
|
||||
```
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Find what's using the port
|
||||
lsof -i :3000
|
||||
netstat -tulpn | grep 3000
|
||||
|
||||
# Find container using port
|
||||
docker ps --format "table {{.Names}}\t{{.Ports}}"
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Use different port
|
||||
docker run -p 3001:3000 image_name
|
||||
|
||||
# Stop container using port
|
||||
docker stop $(docker ps -q --filter publish=3000)
|
||||
|
||||
# Kill process using port
|
||||
kill $(lsof -t -i:3000)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Permission denied
|
||||
|
||||
```
|
||||
permission denied while trying to connect to the Docker daemon socket
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Run with sudo (not recommended for regular use)
|
||||
sudo docker ps
|
||||
|
||||
# Better - add user to docker group
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
|
||||
# Verify
|
||||
groups | grep docker
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### OOMKilled
|
||||
|
||||
```
|
||||
Container killed due to OOM (Out of Memory)
|
||||
```
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
docker inspect container_name | grep -i oom
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Increase memory limit
|
||||
docker run -m 2g image_name
|
||||
|
||||
# In docker-compose.yml
|
||||
services:
|
||||
app:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 2G
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Networking Errors
|
||||
|
||||
### Cannot resolve hostname
|
||||
|
||||
```
|
||||
Could not resolve host: api.example.com
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. No network access
|
||||
2. DNS not configured
|
||||
3. Network mode issue
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check container network
|
||||
docker inspect container_name | grep -A20 NetworkSettings
|
||||
|
||||
# Use host network (development)
|
||||
docker run --network host image_name
|
||||
|
||||
# Add DNS server
|
||||
docker run --dns 8.8.8.8 image_name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Connection refused between containers
|
||||
|
||||
```
|
||||
Error: connect ECONNREFUSED 172.17.0.2:5432
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Containers not on same network
|
||||
2. Using wrong hostname
|
||||
3. Target service not ready
|
||||
|
||||
**Solutions**:
|
||||
```yaml
|
||||
# docker-compose.yml - use service names as hostnames
|
||||
services:
|
||||
app:
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
DATABASE_URL: postgresql://db:5432/mydb # 'db' is the service name
|
||||
|
||||
db:
|
||||
image: postgres
|
||||
```
|
||||
|
||||
```bash
|
||||
# Create network and connect containers
|
||||
docker network create mynetwork
|
||||
docker run --network mynetwork --name db postgres
|
||||
docker run --network mynetwork --name app myapp
|
||||
|
||||
# In app, connect to 'db' hostname
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Network not found
|
||||
|
||||
```
|
||||
network mynetwork not found
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Create network
|
||||
docker network create mynetwork
|
||||
|
||||
# List networks
|
||||
docker network ls
|
||||
|
||||
# In docker-compose, networks are created automatically
|
||||
# Or define explicitly:
|
||||
```
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
mynetwork:
|
||||
driver: bridge
|
||||
|
||||
services:
|
||||
app:
|
||||
networks:
|
||||
- mynetwork
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Volume Errors
|
||||
|
||||
### Volume mount permission denied
|
||||
|
||||
```
|
||||
permission denied: '/app/data'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Container user can't write to mounted directory
|
||||
2. SELinux/AppArmor blocking
|
||||
3. Host directory permissions
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check host directory permissions
|
||||
ls -la /host/path
|
||||
|
||||
# Fix permissions
|
||||
chmod 777 /host/path # Not recommended for production
|
||||
# Or
|
||||
chown 1000:1000 /host/path # Match container user ID
|
||||
|
||||
# SELinux - add :z or :Z suffix
|
||||
docker run -v /host/path:/container/path:z image_name
|
||||
|
||||
# Run as root (not recommended)
|
||||
docker run --user root image_name
|
||||
```
|
||||
|
||||
```dockerfile
|
||||
# In Dockerfile - create directory as root, then switch user
|
||||
RUN mkdir -p /app/data && chown -R node:node /app
|
||||
USER node
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Volume not found
|
||||
|
||||
```
|
||||
Error: No such volume: myvolume
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Create volume
|
||||
docker volume create myvolume
|
||||
|
||||
# List volumes
|
||||
docker volume ls
|
||||
|
||||
# In docker-compose
|
||||
volumes:
|
||||
myvolume:
|
||||
|
||||
services:
|
||||
app:
|
||||
volumes:
|
||||
- myvolume:/app/data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Image Errors
|
||||
|
||||
### Image not found
|
||||
|
||||
```
|
||||
Unable to find image 'myimage:latest' locally
|
||||
Error response from daemon: pull access denied
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Image doesn't exist
|
||||
2. Not logged into registry
|
||||
3. Private image without auth
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check if image exists
|
||||
docker images | grep myimage
|
||||
|
||||
# Login to registry
|
||||
docker login
|
||||
docker login registry.example.com
|
||||
|
||||
# Pull explicitly
|
||||
docker pull myimage:latest
|
||||
|
||||
# For private registries
|
||||
docker pull registry.example.com/myimage:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Manifest not found
|
||||
|
||||
```
|
||||
manifest for image:tag not found
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Tag doesn't exist
|
||||
2. Architecture mismatch (arm64 vs amd64)
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check available tags
|
||||
docker manifest inspect image_name
|
||||
|
||||
# Specify platform
|
||||
docker pull --platform linux/amd64 image_name
|
||||
|
||||
# Build for multiple platforms
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t myimage .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose Errors
|
||||
|
||||
### Service failed to build
|
||||
|
||||
```
|
||||
ERROR: Service 'app' failed to build
|
||||
```
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Build with verbose output
|
||||
docker-compose build --no-cache --progress=plain app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Depends_on not waiting
|
||||
|
||||
```
|
||||
Connection refused to database
|
||||
```
|
||||
|
||||
**Problem**: `depends_on` only waits for container start, not service ready.
|
||||
|
||||
**Solutions**:
|
||||
```yaml
|
||||
# Use healthcheck
|
||||
services:
|
||||
db:
|
||||
image: postgres
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
app:
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
```
|
||||
|
||||
```bash
|
||||
# Or use wait script in app
|
||||
#!/bin/sh
|
||||
until pg_isready -h db -p 5432; do
|
||||
echo "Waiting for database..."
|
||||
sleep 2
|
||||
done
|
||||
exec "$@"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| Cannot connect to daemon | Setup | Start Docker, check permissions |
|
||||
| No space left | Disk | `docker system prune -a` |
|
||||
| COPY failed | Build | Check path relative to build context |
|
||||
| Container exits immediately | Runtime | Add foreground process |
|
||||
| Port already in use | Network | Use different port or stop other container |
|
||||
| OOMKilled | Memory | Increase memory limit with `-m` |
|
||||
| Connection refused between containers | Network | Use same network, service names |
|
||||
| Volume permission denied | Volume | Fix host permissions, use :z |
|
||||
| Image not found | Image | `docker login`, check registry |
|
||||
| Depends_on not waiting | Compose | Use healthcheck with condition |
|
||||
@@ -0,0 +1,529 @@
|
||||
# Git Error Patterns
|
||||
|
||||
Common Git errors with diagnosis and solutions.
|
||||
|
||||
## Push/Pull Errors
|
||||
|
||||
### Failed to push: rejected
|
||||
|
||||
```
|
||||
! [rejected] main -> main (non-fast-forward)
|
||||
error: failed to push some refs to 'origin'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Remote has commits you don't have locally
|
||||
2. Force push required (history rewritten)
|
||||
3. Branch protection rules
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Option 1: Pull and merge first (safest)
|
||||
git pull origin main
|
||||
git push origin main
|
||||
|
||||
# Option 2: Pull with rebase
|
||||
git pull --rebase origin main
|
||||
git push origin main
|
||||
|
||||
# Option 3: Force push (CAREFUL - overwrites remote)
|
||||
# Only if you intentionally rewrote history
|
||||
git push --force-with-lease origin main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Remote contains work you do not have locally
|
||||
|
||||
```
|
||||
hint: Updates were rejected because the remote contains work that you do not have locally.
|
||||
```
|
||||
|
||||
**Same as above** - pull first, then push.
|
||||
|
||||
```bash
|
||||
# Standard workflow
|
||||
git fetch origin
|
||||
git merge origin/main # Or: git rebase origin/main
|
||||
git push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Permission denied (publickey)
|
||||
|
||||
```
|
||||
Permission denied (publickey).
|
||||
fatal: Could not read from remote repository.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. SSH key not added to agent
|
||||
2. SSH key not added to GitHub/GitLab
|
||||
3. Wrong SSH key
|
||||
4. Using HTTPS URL instead of SSH
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Test SSH connection
|
||||
ssh -T git@github.com
|
||||
ssh -vT git@github.com # Verbose for debugging
|
||||
|
||||
# Check loaded keys
|
||||
ssh-add -l
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Add SSH key to agent
|
||||
eval "$(ssh-agent -s)"
|
||||
ssh-add ~/.ssh/id_ed25519 # Or your key file
|
||||
|
||||
# Generate new key if needed
|
||||
ssh-keygen -t ed25519 -C "your@email.com"
|
||||
|
||||
# Copy public key to GitHub/GitLab
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
# Then add in GitHub Settings -> SSH Keys
|
||||
|
||||
# Or use HTTPS instead of SSH
|
||||
git remote set-url origin https://github.com/user/repo.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Authentication failed
|
||||
|
||||
```
|
||||
remote: Invalid username or password.
|
||||
fatal: Authentication failed for 'https://github.com/...'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Wrong credentials
|
||||
2. Password auth disabled (GitHub)
|
||||
3. Token expired
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Use Personal Access Token instead of password
|
||||
# Generate at: GitHub -> Settings -> Developer settings -> Personal access tokens
|
||||
|
||||
# Update stored credentials
|
||||
git credential reject
|
||||
protocol=https
|
||||
host=github.com
|
||||
# Press Enter twice
|
||||
|
||||
# Or use credential helper
|
||||
git config --global credential.helper cache
|
||||
git config --global credential.helper 'cache --timeout=3600'
|
||||
|
||||
# Or switch to SSH
|
||||
git remote set-url origin git@github.com:user/repo.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Merge Conflicts
|
||||
|
||||
### Automatic merge failed
|
||||
|
||||
```
|
||||
CONFLICT (content): Merge conflict in file.js
|
||||
Automatic merge failed; fix conflicts and then commit the result.
|
||||
```
|
||||
|
||||
**Resolution Workflow**:
|
||||
```bash
|
||||
# 1. See conflicting files
|
||||
git status
|
||||
|
||||
# 2. Open file and look for conflict markers
|
||||
<<<<<<< HEAD
|
||||
your changes
|
||||
=======
|
||||
their changes
|
||||
>>>>>>> branch-name
|
||||
|
||||
# 3. Edit file to resolve (remove markers, keep desired code)
|
||||
|
||||
# 4. Stage resolved files
|
||||
git add file.js
|
||||
|
||||
# 5. Complete merge
|
||||
git commit
|
||||
# Or if rebasing: git rebase --continue
|
||||
```
|
||||
|
||||
**Tools**:
|
||||
```bash
|
||||
# Use merge tool
|
||||
git mergetool
|
||||
|
||||
# Configure VS Code as merge tool
|
||||
git config --global merge.tool vscode
|
||||
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
|
||||
```
|
||||
|
||||
**Abort if needed**:
|
||||
```bash
|
||||
git merge --abort
|
||||
# Or
|
||||
git rebase --abort
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cannot pull with rebase: unstaged changes
|
||||
|
||||
```
|
||||
error: cannot pull with rebase: You have unstaged changes.
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Option 1: Stash changes
|
||||
git stash
|
||||
git pull --rebase
|
||||
git stash pop
|
||||
|
||||
# Option 2: Commit changes first
|
||||
git add .
|
||||
git commit -m "WIP"
|
||||
git pull --rebase
|
||||
|
||||
# Option 3: Discard changes (CAREFUL)
|
||||
git checkout -- .
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checkout/Switch Errors
|
||||
|
||||
### Cannot checkout: local changes would be overwritten
|
||||
|
||||
```
|
||||
error: Your local changes to the following files would be overwritten by checkout
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Option 1: Stash changes
|
||||
git stash
|
||||
git checkout other-branch
|
||||
git stash pop # To get changes back
|
||||
|
||||
# Option 2: Commit changes
|
||||
git add .
|
||||
git commit -m "WIP"
|
||||
git checkout other-branch
|
||||
|
||||
# Option 3: Discard changes (CAREFUL)
|
||||
git checkout -- file.js # Single file
|
||||
git checkout -- . # All files
|
||||
git reset --hard # Everything including staged
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Pathspec did not match any file
|
||||
|
||||
```
|
||||
error: pathspec 'branch-name' did not match any file(s) known to git
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Branch doesn't exist
|
||||
2. Typo in branch name
|
||||
3. Remote branch not fetched
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# List all branches
|
||||
git branch -a
|
||||
|
||||
# Fetch remote branches
|
||||
git fetch origin
|
||||
|
||||
# Checkout remote branch
|
||||
git checkout -b branch-name origin/branch-name
|
||||
# Or (newer Git)
|
||||
git switch branch-name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reset/Revert Errors
|
||||
|
||||
### HEAD detached
|
||||
|
||||
```
|
||||
You are in 'detached HEAD' state.
|
||||
```
|
||||
|
||||
**What it means**: You checked out a commit, not a branch.
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Go back to branch
|
||||
git checkout main
|
||||
|
||||
# Create new branch from current state
|
||||
git checkout -b new-branch-name
|
||||
|
||||
# See where HEAD is
|
||||
git log --oneline -1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cannot do soft reset with paths
|
||||
|
||||
```
|
||||
fatal: Cannot do soft reset with paths.
|
||||
```
|
||||
|
||||
**Solution**: Use different command:
|
||||
```bash
|
||||
# To unstage file
|
||||
git restore --staged file.js
|
||||
# Or older Git:
|
||||
git reset HEAD file.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Refusing to reset in dirty worktree
|
||||
|
||||
```
|
||||
fatal: Failed to resolve 'HEAD~1' as a valid ref.
|
||||
```
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Stash changes first
|
||||
git stash
|
||||
git reset --hard HEAD~1
|
||||
git stash pop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stash Errors
|
||||
|
||||
### No stash entries found
|
||||
|
||||
```
|
||||
No stash entries found.
|
||||
```
|
||||
|
||||
**Check stashes**:
|
||||
```bash
|
||||
# List all stashes
|
||||
git stash list
|
||||
|
||||
# If empty, nothing was stashed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Conflict when applying stash
|
||||
|
||||
```
|
||||
CONFLICT (content): Merge conflict in file.js
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Resolve conflicts manually (same as merge conflicts)
|
||||
# Then either:
|
||||
git stash drop # Remove stash after resolving
|
||||
|
||||
# Or if you want to keep stash:
|
||||
# Just resolve conflicts, add, and commit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rebase Errors
|
||||
|
||||
### Cannot rebase: uncommitted changes
|
||||
|
||||
```
|
||||
error: cannot rebase: You have unstaged changes.
|
||||
```
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
git stash
|
||||
git rebase origin/main
|
||||
git stash pop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Rebase conflict
|
||||
|
||||
```
|
||||
CONFLICT (content): Merge conflict in file.js
|
||||
error: could not apply abc1234... commit message
|
||||
```
|
||||
|
||||
**Resolution**:
|
||||
```bash
|
||||
# 1. Fix conflicts in files
|
||||
|
||||
# 2. Stage resolved files
|
||||
git add file.js
|
||||
|
||||
# 3. Continue rebase
|
||||
git rebase --continue
|
||||
|
||||
# Or abort entire rebase
|
||||
git rebase --abort
|
||||
|
||||
# Skip this commit (lose its changes)
|
||||
git rebase --skip
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Submodule Errors
|
||||
|
||||
### Submodule not initialized
|
||||
|
||||
```
|
||||
fatal: no submodule mapping found in .gitmodules for path 'submodule-path'
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Initialize submodules
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
# Or clone with submodules
|
||||
git clone --recurse-submodules repo-url
|
||||
|
||||
# Update existing clone
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Submodule HEAD detached
|
||||
|
||||
```
|
||||
HEAD detached at abc1234
|
||||
```
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
cd submodule-path
|
||||
git checkout main # Or desired branch
|
||||
cd ..
|
||||
git add submodule-path
|
||||
git commit -m "Update submodule to main"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LFS Errors
|
||||
|
||||
### File exceeds GitHub file size limit
|
||||
|
||||
```
|
||||
remote: error: File large-file.zip is 150.00 MB; this exceeds GitHub's file size limit of 100.00 MB
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Install Git LFS
|
||||
brew install git-lfs # macOS
|
||||
git lfs install
|
||||
|
||||
# Track large files
|
||||
git lfs track "*.zip"
|
||||
git lfs track "*.psd"
|
||||
git add .gitattributes
|
||||
|
||||
# If already committed, need to rewrite history
|
||||
git filter-branch --tree-filter 'git lfs track "*.zip"' HEAD
|
||||
# Or use BFG Repo Cleaner
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### LFS objects missing
|
||||
|
||||
```
|
||||
Encountered 1 file that should have been a pointer, but wasn't
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Fetch LFS objects
|
||||
git lfs fetch --all
|
||||
|
||||
# Or pull LFS objects
|
||||
git lfs pull
|
||||
|
||||
# Migrate existing files to LFS
|
||||
git lfs migrate import --include="*.psd"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration Errors
|
||||
|
||||
### Author identity unknown
|
||||
|
||||
```
|
||||
Author identity unknown
|
||||
Please tell me who you are.
|
||||
```
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
git config --global user.email "you@example.com"
|
||||
git config --global user.name "Your Name"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Unsafe repository
|
||||
|
||||
```
|
||||
fatal: detected dubious ownership in repository
|
||||
```
|
||||
|
||||
**Causes**: Repository owned by different user (common in Docker/WSL).
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Add exception for this repo
|
||||
git config --global --add safe.directory /path/to/repo
|
||||
|
||||
# Or for all repos (less secure)
|
||||
git config --global --add safe.directory '*'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| Push rejected | Push | `git pull --rebase` then push |
|
||||
| Permission denied | Auth | Check SSH key: `ssh-add -l` |
|
||||
| Auth failed | Auth | Use Personal Access Token |
|
||||
| Merge conflict | Merge | Edit file, remove markers, `git add` |
|
||||
| Unstaged changes | Checkout | `git stash` first |
|
||||
| Pathspec not found | Branch | `git fetch` then checkout |
|
||||
| HEAD detached | Branch | `git checkout main` |
|
||||
| No stash entries | Stash | Nothing was stashed |
|
||||
| Rebase conflict | Rebase | Fix conflict, `git rebase --continue` |
|
||||
| File too large | LFS | Use Git LFS for large files |
|
||||
| Identity unknown | Config | Set user.email and user.name |
|
||||
@@ -0,0 +1,537 @@
|
||||
# Go Error Patterns
|
||||
|
||||
Common Go errors with diagnosis and solutions.
|
||||
|
||||
## Nil Pointer Errors
|
||||
|
||||
### panic: runtime error: invalid memory address or nil pointer dereference
|
||||
|
||||
```go
|
||||
panic: runtime error: invalid memory address or nil pointer dereference
|
||||
[signal SIGSEGV: segmentation violation]
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Calling method on nil pointer
|
||||
2. Accessing field of nil struct
|
||||
3. Dereferencing nil pointer
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Check for nil before use
|
||||
if user != nil {
|
||||
fmt.Println(user.Name)
|
||||
}
|
||||
|
||||
// Return early on nil
|
||||
func processUser(user *User) error {
|
||||
if user == nil {
|
||||
return errors.New("user is nil")
|
||||
}
|
||||
// proceed
|
||||
}
|
||||
|
||||
// Use zero values where appropriate
|
||||
type Config struct {
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func (c *Config) GetTimeout() time.Duration {
|
||||
if c == nil {
|
||||
return 30 * time.Second // default
|
||||
}
|
||||
return c.Timeout
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Slice/Array Errors
|
||||
|
||||
### panic: runtime error: index out of range
|
||||
|
||||
```go
|
||||
panic: runtime error: index out of range [5] with length 3
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Accessing index beyond slice length
|
||||
2. Empty slice access
|
||||
3. Off-by-one error
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Check length first
|
||||
if len(items) > index {
|
||||
item := items[index]
|
||||
}
|
||||
|
||||
// Safe first/last element
|
||||
func first(items []string) (string, bool) {
|
||||
if len(items) == 0 {
|
||||
return "", false
|
||||
}
|
||||
return items[0], true
|
||||
}
|
||||
|
||||
// Use range for iteration
|
||||
for i, item := range items {
|
||||
// safe access
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### panic: runtime error: slice bounds out of range
|
||||
|
||||
```go
|
||||
panic: runtime error: slice bounds out of range [:5] with length 3
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Validate slice bounds
|
||||
func safeSlice(s []int, start, end int) []int {
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
if end > len(s) {
|
||||
end = len(s)
|
||||
}
|
||||
if start > end {
|
||||
return nil
|
||||
}
|
||||
return s[start:end]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Map Errors
|
||||
|
||||
### panic: assignment to entry in nil map
|
||||
|
||||
```go
|
||||
panic: assignment to entry in nil map
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Writing to uninitialized map
|
||||
2. Map declared but not made
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Wrong
|
||||
var m map[string]int
|
||||
m["key"] = 1 // panic!
|
||||
|
||||
// Correct - use make
|
||||
m := make(map[string]int)
|
||||
m["key"] = 1
|
||||
|
||||
// Or initialize with literal
|
||||
m := map[string]int{}
|
||||
m["key"] = 1
|
||||
|
||||
// In structs, initialize in constructor
|
||||
type Cache struct {
|
||||
data map[string]string
|
||||
}
|
||||
|
||||
func NewCache() *Cache {
|
||||
return &Cache{
|
||||
data: make(map[string]string),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Map access returns zero value
|
||||
|
||||
```go
|
||||
value := m["nonexistent"] // Returns zero value, not error
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Check if key exists
|
||||
value, ok := m["key"]
|
||||
if !ok {
|
||||
// key doesn't exist
|
||||
}
|
||||
|
||||
// Or use default
|
||||
func getOrDefault(m map[string]int, key string, def int) int {
|
||||
if v, ok := m[key]; ok {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Channel Errors
|
||||
|
||||
### fatal error: all goroutines are asleep - deadlock!
|
||||
|
||||
```go
|
||||
fatal error: all goroutines are asleep - deadlock!
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Channel send/receive with no corresponding operation
|
||||
2. Unbuffered channel blocking
|
||||
3. Waiting on channel that's never written to
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Wrong - unbuffered channel blocks
|
||||
ch := make(chan int)
|
||||
ch <- 1 // blocks forever, no receiver
|
||||
|
||||
// Correct - use goroutine
|
||||
ch := make(chan int)
|
||||
go func() {
|
||||
ch <- 1
|
||||
}()
|
||||
value := <-ch
|
||||
|
||||
// Or use buffered channel
|
||||
ch := make(chan int, 1)
|
||||
ch <- 1 // doesn't block
|
||||
value := <-ch
|
||||
|
||||
// Always close channels when done sending
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for _, item := range items {
|
||||
ch <- item
|
||||
}
|
||||
}()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### panic: send on closed channel
|
||||
|
||||
```go
|
||||
panic: send on closed channel
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Only sender should close channel
|
||||
// Use sync.Once for safe closing
|
||||
var once sync.Once
|
||||
closeCh := func() {
|
||||
once.Do(func() {
|
||||
close(ch)
|
||||
})
|
||||
}
|
||||
|
||||
// Or use context for cancellation
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case ch <- value:
|
||||
}
|
||||
}
|
||||
}()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interface Errors
|
||||
|
||||
### panic: interface conversion: X is nil, not Y
|
||||
|
||||
```go
|
||||
panic: interface conversion: interface {} is nil, not string
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Use type assertion with ok
|
||||
value, ok := i.(string)
|
||||
if !ok {
|
||||
// handle non-string or nil
|
||||
}
|
||||
|
||||
// Use type switch
|
||||
switch v := i.(type) {
|
||||
case string:
|
||||
fmt.Println("string:", v)
|
||||
case int:
|
||||
fmt.Println("int:", v)
|
||||
case nil:
|
||||
fmt.Println("nil")
|
||||
default:
|
||||
fmt.Println("unknown type")
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### panic: interface conversion: X is Y, not Z
|
||||
|
||||
```go
|
||||
panic: interface conversion: interface {} is int, not string
|
||||
```
|
||||
|
||||
**Same solution** - always use type assertion with `ok` check.
|
||||
|
||||
---
|
||||
|
||||
## Concurrency Errors
|
||||
|
||||
### fatal error: concurrent map writes
|
||||
|
||||
```go
|
||||
fatal error: concurrent map writes
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Multiple goroutines writing to same map
|
||||
2. No synchronization
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Option 1: Use sync.Mutex
|
||||
type SafeMap struct {
|
||||
mu sync.RWMutex
|
||||
m map[string]int
|
||||
}
|
||||
|
||||
func (s *SafeMap) Set(key string, value int) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.m[key] = value
|
||||
}
|
||||
|
||||
func (s *SafeMap) Get(key string) (int, bool) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
v, ok := s.m[key]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
// Option 2: Use sync.Map
|
||||
var m sync.Map
|
||||
m.Store("key", 1)
|
||||
value, ok := m.Load("key")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### data race detected
|
||||
|
||||
```
|
||||
WARNING: DATA RACE
|
||||
Write by goroutine X:
|
||||
...
|
||||
Previous read by goroutine Y:
|
||||
...
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Use mutex for shared state
|
||||
var (
|
||||
mu sync.Mutex
|
||||
count int
|
||||
)
|
||||
|
||||
func increment() {
|
||||
mu.Lock()
|
||||
count++
|
||||
mu.Unlock()
|
||||
}
|
||||
|
||||
// Or use atomic operations
|
||||
var count int64
|
||||
|
||||
func increment() {
|
||||
atomic.AddInt64(&count, 1)
|
||||
}
|
||||
|
||||
// Run with race detector
|
||||
// go run -race main.go
|
||||
// go test -race ./...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Import/Module Errors
|
||||
|
||||
### cannot find package
|
||||
|
||||
```
|
||||
cannot find package "github.com/user/repo" in any of:
|
||||
/usr/local/go/src/github.com/user/repo (from $GOROOT)
|
||||
/home/user/go/src/github.com/user/repo (from $GOPATH)
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Initialize go modules
|
||||
go mod init myproject
|
||||
|
||||
# Download dependencies
|
||||
go mod tidy
|
||||
|
||||
# Or get specific package
|
||||
go get github.com/user/repo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### module declares its path as X but was required as Y
|
||||
|
||||
```
|
||||
module declares its path as: github.com/old/path
|
||||
but was required as: github.com/new/path
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Update go.mod with replace directive
|
||||
# go.mod
|
||||
replace github.com/old/path => github.com/new/path v1.0.0
|
||||
|
||||
# Or update import paths in code
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### Wrapping Errors (Go 1.13+)
|
||||
|
||||
```go
|
||||
// Wrap with context
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to process user %d: %w", userID, err)
|
||||
}
|
||||
|
||||
// Unwrap to check original error
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
// handle not found
|
||||
}
|
||||
|
||||
// Get specific error type
|
||||
var pathErr *os.PathError
|
||||
if errors.As(err, &pathErr) {
|
||||
fmt.Println("Path:", pathErr.Path)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Custom Errors
|
||||
|
||||
```go
|
||||
// Sentinel errors
|
||||
var ErrNotFound = errors.New("not found")
|
||||
|
||||
// Custom error type
|
||||
type ValidationError struct {
|
||||
Field string
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *ValidationError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.Field, e.Message)
|
||||
}
|
||||
|
||||
// Check with errors.As
|
||||
var valErr *ValidationError
|
||||
if errors.As(err, &valErr) {
|
||||
fmt.Printf("Validation failed on %s\n", valErr.Field)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build Errors
|
||||
|
||||
### undefined: X
|
||||
|
||||
```
|
||||
./main.go:10:2: undefined: someFunction
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Function/variable not defined
|
||||
2. Wrong package imported
|
||||
3. Unexported name (lowercase)
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Check export - must be uppercase
|
||||
func PublicFunction() {} // Exported
|
||||
func privateFunction() {} // Not exported
|
||||
|
||||
// Check import
|
||||
import "mypackage"
|
||||
mypackage.PublicFunction()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### imported and not used
|
||||
|
||||
```
|
||||
./main.go:4:2: "fmt" imported and not used
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Remove unused import
|
||||
// Or use blank identifier if needed for side effects
|
||||
import _ "database/sql/driver"
|
||||
|
||||
// Use goimports to auto-fix
|
||||
// goimports -w .
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### declared and not used
|
||||
|
||||
```
|
||||
./main.go:10:2: x declared and not used
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```go
|
||||
// Use the variable or remove it
|
||||
// Use blank identifier if intentionally unused
|
||||
_ = someFunction()
|
||||
|
||||
// For error checking
|
||||
result, _ := riskyFunction() // Intentionally ignore error (not recommended)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| nil pointer dereference | Nil | Check for nil before use |
|
||||
| index out of range | Slice | Check `len()` first |
|
||||
| assignment to nil map | Map | Use `make(map[K]V)` |
|
||||
| deadlock | Channel | Ensure send/receive pairs match |
|
||||
| send on closed channel | Channel | Only sender closes |
|
||||
| interface conversion nil | Interface | Use type assertion with ok |
|
||||
| concurrent map writes | Concurrency | Use `sync.Mutex` or `sync.Map` |
|
||||
| data race | Concurrency | Add synchronization, use `-race` |
|
||||
| cannot find package | Module | Run `go mod tidy` |
|
||||
| undefined | Build | Check export (uppercase) |
|
||||
@@ -0,0 +1,625 @@
|
||||
# Network & API Error Patterns
|
||||
|
||||
Common network and API errors with diagnosis and solutions.
|
||||
|
||||
## HTTP Status Errors
|
||||
|
||||
### 400 Bad Request
|
||||
|
||||
```
|
||||
HTTP 400 Bad Request
|
||||
{"error": "Bad Request", "message": "Invalid JSON"}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Malformed JSON body
|
||||
2. Missing required fields
|
||||
3. Invalid field values
|
||||
4. Wrong Content-Type header
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Validate JSON
|
||||
echo '{"key": "value"}' | jq .
|
||||
|
||||
# Check request
|
||||
curl -v -X POST https://api.example.com/endpoint \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"key": "value"}'
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Check Content-Type
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json', // Not 'text/plain'
|
||||
},
|
||||
body: JSON.stringify(data), // Not just data
|
||||
})
|
||||
|
||||
// Validate before sending
|
||||
if (!data.required_field) {
|
||||
throw new Error('Missing required_field')
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 401 Unauthorized
|
||||
|
||||
```
|
||||
HTTP 401 Unauthorized
|
||||
{"error": "Unauthorized", "message": "Invalid or expired token"}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Missing auth token
|
||||
2. Expired token
|
||||
3. Invalid token format
|
||||
4. Wrong auth scheme
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Check Authorization header format
|
||||
fetch(url, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`, // Note: "Bearer " prefix
|
||||
},
|
||||
})
|
||||
|
||||
// Refresh token if expired
|
||||
async function fetchWithAuth(url) {
|
||||
let response = await fetch(url, {
|
||||
headers: { 'Authorization': `Bearer ${accessToken}` }
|
||||
})
|
||||
|
||||
if (response.status === 401) {
|
||||
accessToken = await refreshToken()
|
||||
response = await fetch(url, {
|
||||
headers: { 'Authorization': `Bearer ${accessToken}` }
|
||||
})
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 403 Forbidden
|
||||
|
||||
```
|
||||
HTTP 403 Forbidden
|
||||
{"error": "Forbidden", "message": "Insufficient permissions"}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Authenticated but not authorized
|
||||
2. Resource access denied
|
||||
3. Rate limiting
|
||||
4. IP blocked
|
||||
|
||||
**Different from 401**: 401 = "Who are you?" 403 = "I know who you are, but no."
|
||||
|
||||
**Solutions**:
|
||||
- Check user permissions/roles
|
||||
- Verify API key scopes
|
||||
- Check rate limit headers
|
||||
- Verify IP whitelist
|
||||
|
||||
---
|
||||
|
||||
### 404 Not Found
|
||||
|
||||
```
|
||||
HTTP 404 Not Found
|
||||
{"error": "Not Found", "message": "Resource not found"}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Wrong URL/endpoint
|
||||
2. Resource deleted
|
||||
3. ID doesn't exist
|
||||
4. Trailing slash issues
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check URL is correct
|
||||
curl -I https://api.example.com/users/123
|
||||
|
||||
# Try with/without trailing slash
|
||||
curl https://api.example.com/users/
|
||||
curl https://api.example.com/users
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Handle 404 gracefully
|
||||
const response = await fetch(`/api/users/${id}`)
|
||||
if (response.status === 404) {
|
||||
return null // Or throw custom error
|
||||
}
|
||||
return response.json()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 405 Method Not Allowed
|
||||
|
||||
```
|
||||
HTTP 405 Method Not Allowed
|
||||
{"error": "Method Not Allowed", "allowed": ["GET", "POST"]}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Using wrong HTTP method
|
||||
2. Endpoint doesn't support method
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check allowed methods
|
||||
curl -I -X OPTIONS https://api.example.com/endpoint
|
||||
# Look for Allow header
|
||||
|
||||
# Use correct method
|
||||
curl -X POST https://api.example.com/users # Not GET
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 429 Too Many Requests
|
||||
|
||||
```
|
||||
HTTP 429 Too Many Requests
|
||||
{"error": "Rate Limited", "retry_after": 60}
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Rate limit exceeded
|
||||
2. Too many concurrent requests
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Implement exponential backoff
|
||||
async function fetchWithRetry(url, maxRetries = 3) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
const response = await fetch(url)
|
||||
|
||||
if (response.status === 429) {
|
||||
const retryAfter = response.headers.get('Retry-After') || 60
|
||||
await sleep(retryAfter * 1000 * (i + 1))
|
||||
continue
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
throw new Error('Max retries exceeded')
|
||||
}
|
||||
|
||||
// Rate limiting in client
|
||||
const limiter = new RateLimiter({
|
||||
tokensPerInterval: 10,
|
||||
interval: 'second',
|
||||
})
|
||||
|
||||
async function limitedFetch(url) {
|
||||
await limiter.removeTokens(1)
|
||||
return fetch(url)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 500 Internal Server Error
|
||||
|
||||
```
|
||||
HTTP 500 Internal Server Error
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server-side bug
|
||||
2. Unhandled exception
|
||||
3. Database error
|
||||
4. Third-party service failure
|
||||
|
||||
**What you can do**:
|
||||
1. Check if your request is valid
|
||||
2. Retry later
|
||||
3. Report to API provider with request details
|
||||
|
||||
---
|
||||
|
||||
### 502 Bad Gateway
|
||||
|
||||
```
|
||||
HTTP 502 Bad Gateway
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Upstream server down
|
||||
2. Proxy misconfiguration
|
||||
3. Load balancer issues
|
||||
|
||||
**Solutions**:
|
||||
- Usually temporary - retry later
|
||||
- Check service status page
|
||||
- Implement retry logic
|
||||
|
||||
---
|
||||
|
||||
### 503 Service Unavailable
|
||||
|
||||
```
|
||||
HTTP 503 Service Unavailable
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server overloaded
|
||||
2. Maintenance mode
|
||||
3. Capacity issues
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Helper function
|
||||
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
// Retry with exponential backoff
|
||||
async function fetchWithBackoff(url) {
|
||||
const maxRetries = 5
|
||||
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
const response = await fetch(url)
|
||||
if (response.status === 503) {
|
||||
await sleep(Math.pow(2, i) * 1000) // 1s, 2s, 4s, 8s, 16s
|
||||
continue
|
||||
}
|
||||
return response
|
||||
} catch (error) {
|
||||
if (i === maxRetries - 1) throw error
|
||||
await sleep(Math.pow(2, i) * 1000)
|
||||
}
|
||||
}
|
||||
throw new Error('Max retries exceeded')
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 504 Gateway Timeout
|
||||
|
||||
```
|
||||
HTTP 504 Gateway Timeout
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Upstream server too slow
|
||||
2. Long-running operation
|
||||
3. Network timeout
|
||||
|
||||
**Solutions**:
|
||||
- Increase timeout settings
|
||||
- Use async/webhook pattern for long operations
|
||||
- Implement pagination for large responses
|
||||
|
||||
---
|
||||
|
||||
## Connection Errors
|
||||
|
||||
### ECONNREFUSED
|
||||
|
||||
```
|
||||
Error: connect ECONNREFUSED 127.0.0.1:3000
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server not running
|
||||
2. Wrong port
|
||||
3. Firewall blocking
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check if port is listening
|
||||
lsof -i :3000
|
||||
netstat -an | grep 3000
|
||||
curl -v http://localhost:3000
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
1. Start the server
|
||||
2. Check port configuration
|
||||
3. Check firewall rules
|
||||
|
||||
---
|
||||
|
||||
### ENOTFOUND
|
||||
|
||||
```
|
||||
Error: getaddrinfo ENOTFOUND api.example.com
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Invalid hostname
|
||||
2. DNS resolution failure
|
||||
3. No internet connection
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Test DNS
|
||||
nslookup api.example.com
|
||||
dig api.example.com
|
||||
ping api.example.com
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
1. Check URL spelling
|
||||
2. Try different DNS (8.8.8.8)
|
||||
3. Check internet connection
|
||||
4. Check /etc/hosts file
|
||||
|
||||
---
|
||||
|
||||
### ETIMEDOUT
|
||||
|
||||
```
|
||||
Error: connect ETIMEDOUT
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server not responding
|
||||
2. Firewall silently dropping
|
||||
3. Network congestion
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Increase timeout
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), 30000)
|
||||
|
||||
try {
|
||||
const response = await fetch(url, { signal: controller.signal })
|
||||
clearTimeout(timeoutId)
|
||||
return response
|
||||
} catch (error) {
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error('Request timed out')
|
||||
}
|
||||
throw error
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ECONNRESET
|
||||
|
||||
```
|
||||
Error: read ECONNRESET
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server closed connection unexpectedly
|
||||
2. Network interruption
|
||||
3. Server crashed
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Implement retry logic
|
||||
async function fetchWithRetry(url, retries = 3) {
|
||||
for (let i = 0; i < retries; i++) {
|
||||
try {
|
||||
return await fetch(url)
|
||||
} catch (error) {
|
||||
if (error.code === 'ECONNRESET' && i < retries - 1) {
|
||||
await sleep(1000 * (i + 1))
|
||||
continue
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### SSL/TLS Errors
|
||||
|
||||
#### UNABLE_TO_VERIFY_LEAF_SIGNATURE
|
||||
|
||||
```
|
||||
Error: unable to verify the first certificate
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Self-signed certificate
|
||||
2. Missing intermediate certificate
|
||||
3. Expired certificate
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Development only - disable verification (NOT FOR PRODUCTION)
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
|
||||
|
||||
// Better - add CA certificate
|
||||
const https = require('https')
|
||||
const agent = new https.Agent({
|
||||
ca: fs.readFileSync('ca-cert.pem'),
|
||||
})
|
||||
fetch(url, { agent })
|
||||
```
|
||||
|
||||
#### CERT_HAS_EXPIRED
|
||||
|
||||
```
|
||||
Error: certificate has expired
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
1. Update server certificate
|
||||
2. Check system time is correct
|
||||
3. Update CA certificates: `update-ca-certificates`
|
||||
|
||||
---
|
||||
|
||||
## CORS Errors
|
||||
|
||||
### Access-Control-Allow-Origin
|
||||
|
||||
```
|
||||
Access to fetch at 'https://api.example.com' from origin 'https://myapp.com'
|
||||
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server doesn't allow cross-origin requests
|
||||
2. Missing CORS headers
|
||||
3. Credentials mode mismatch
|
||||
|
||||
**Solutions (Server-side)**:
|
||||
```javascript
|
||||
// Express.js
|
||||
const cors = require('cors')
|
||||
app.use(cors({
|
||||
origin: 'https://myapp.com', // Or '*' for all (not recommended)
|
||||
credentials: true,
|
||||
}))
|
||||
|
||||
// Manual headers
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', 'https://myapp.com')
|
||||
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
res.header('Access-Control-Allow-Credentials', 'true')
|
||||
next()
|
||||
})
|
||||
```
|
||||
|
||||
**Solutions (Client-side workarounds)**:
|
||||
```javascript
|
||||
// Use proxy in development
|
||||
// vite.config.js
|
||||
export default {
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'https://api.example.com',
|
||||
changeOrigin: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then fetch from /api instead
|
||||
fetch('/api/endpoint')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Preflight Request Failed
|
||||
|
||||
```
|
||||
Response to preflight request doesn't pass access control check
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. OPTIONS request not handled
|
||||
2. Missing preflight headers
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Handle OPTIONS request
|
||||
app.options('*', cors()) // Express with cors
|
||||
|
||||
// Or manually
|
||||
app.options('*', (req, res) => {
|
||||
res.header('Access-Control-Allow-Origin', '*')
|
||||
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
res.sendStatus(200)
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JSON Parsing Errors
|
||||
|
||||
### Unexpected token < in JSON
|
||||
|
||||
```
|
||||
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server returned HTML instead of JSON (error page, 404)
|
||||
2. Wrong endpoint
|
||||
3. Auth redirect
|
||||
|
||||
**Diagnosis**:
|
||||
```javascript
|
||||
const response = await fetch(url)
|
||||
console.log('Status:', response.status)
|
||||
console.log('Content-Type:', response.headers.get('content-type'))
|
||||
const text = await response.text()
|
||||
console.log('Body:', text.substring(0, 200))
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Check response before parsing
|
||||
const response = await fetch(url)
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text()
|
||||
throw new Error(`HTTP ${response.status}: ${text}`)
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('content-type')
|
||||
if (!contentType?.includes('application/json')) {
|
||||
throw new Error(`Expected JSON, got ${contentType}`)
|
||||
}
|
||||
|
||||
return response.json()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Unexpected end of JSON input
|
||||
|
||||
```
|
||||
SyntaxError: Unexpected end of JSON input
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Empty response body
|
||||
2. Truncated response
|
||||
3. Network interruption
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Check for empty response
|
||||
const text = await response.text()
|
||||
if (!text) {
|
||||
return null // Or default value
|
||||
}
|
||||
return JSON.parse(text)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| 400 Bad Request | Client | Check JSON format, Content-Type |
|
||||
| 401 Unauthorized | Auth | Check token, refresh if expired |
|
||||
| 403 Forbidden | Auth | Check permissions, rate limits |
|
||||
| 404 Not Found | Client | Verify URL, check resource exists |
|
||||
| 429 Too Many Requests | Rate Limit | Implement backoff, reduce requests |
|
||||
| 500 Internal Server Error | Server | Retry, report to provider |
|
||||
| 503 Service Unavailable | Server | Retry with exponential backoff |
|
||||
| ECONNREFUSED | Connection | Start server, check port |
|
||||
| ENOTFOUND | DNS | Check hostname, DNS settings |
|
||||
| ETIMEDOUT | Timeout | Increase timeout, check network |
|
||||
| CORS blocked | Browser | Add CORS headers server-side |
|
||||
| Unexpected token < | Parse | Check response is JSON not HTML |
|
||||
@@ -0,0 +1,600 @@
|
||||
# Node.js Error Patterns
|
||||
|
||||
Common Node.js errors with diagnosis and solutions.
|
||||
|
||||
## Module Errors
|
||||
|
||||
### MODULE_NOT_FOUND
|
||||
|
||||
```
|
||||
Error: Cannot find module 'package-name'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Package not installed
|
||||
2. Typo in import/require
|
||||
3. node_modules corrupted
|
||||
4. Wrong relative path
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Install missing package
|
||||
npm install package-name
|
||||
|
||||
# If corrupted node_modules
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
|
||||
# Check if package exists
|
||||
npm ls package-name
|
||||
```
|
||||
|
||||
**Prevention**: Use `npm ci` in CI/CD, add postinstall check.
|
||||
|
||||
---
|
||||
|
||||
### ERR_MODULE_NOT_FOUND (ESM)
|
||||
|
||||
```
|
||||
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'x' imported from y
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. ESM import without file extension
|
||||
2. Package doesn't support ESM
|
||||
3. Missing `"type": "module"` in package.json
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Add file extension for local imports
|
||||
import { foo } from './utils.js' // Not './utils'
|
||||
|
||||
// For CommonJS packages, use createRequire
|
||||
import { createRequire } from 'module'
|
||||
const require = createRequire(import.meta.url)
|
||||
const pkg = require('commonjs-package')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Network Errors
|
||||
|
||||
### ECONNREFUSED
|
||||
|
||||
```
|
||||
Error: connect ECONNREFUSED 127.0.0.1:3000
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server not running
|
||||
2. Wrong port
|
||||
3. Firewall blocking
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check if port is in use
|
||||
lsof -i :3000
|
||||
netstat -an | grep 3000
|
||||
|
||||
# Check if service is running
|
||||
ps aux | grep node
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
1. Start the server first
|
||||
2. Verify port number matches
|
||||
3. Check firewall rules
|
||||
|
||||
---
|
||||
|
||||
### ENOTFOUND
|
||||
|
||||
```
|
||||
Error: getaddrinfo ENOTFOUND hostname
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Invalid hostname/URL
|
||||
2. DNS resolution failure
|
||||
3. No internet connection
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Test DNS resolution
|
||||
nslookup hostname
|
||||
dig hostname
|
||||
|
||||
# Test connectivity
|
||||
ping hostname
|
||||
curl -I https://hostname
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
1. Check URL spelling
|
||||
2. Try IP address instead of hostname
|
||||
3. Check /etc/hosts file
|
||||
4. Check DNS settings
|
||||
|
||||
---
|
||||
|
||||
### ETIMEDOUT
|
||||
|
||||
```
|
||||
Error: connect ETIMEDOUT
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Network too slow
|
||||
2. Server overloaded
|
||||
3. Firewall silently dropping
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Increase timeout
|
||||
const axios = require('axios')
|
||||
axios.get(url, { timeout: 30000 })
|
||||
|
||||
// With fetch
|
||||
const controller = new AbortController()
|
||||
setTimeout(() => controller.abort(), 30000)
|
||||
fetch(url, { signal: controller.signal })
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File System Errors
|
||||
|
||||
### ENOENT
|
||||
|
||||
```
|
||||
Error: ENOENT: no such file or directory, open 'path/to/file'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. File doesn't exist
|
||||
2. Wrong path (relative vs absolute)
|
||||
3. Typo in filename
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check if file exists
|
||||
ls -la path/to/file
|
||||
|
||||
# Check current working directory
|
||||
pwd
|
||||
|
||||
# List directory contents
|
||||
ls -la path/to/
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Check before accessing
|
||||
const fs = require('fs')
|
||||
if (fs.existsSync(filePath)) {
|
||||
// proceed
|
||||
}
|
||||
|
||||
// Use path.join for cross-platform
|
||||
const path = require('path')
|
||||
const filePath = path.join(__dirname, 'data', 'file.json')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### EACCES
|
||||
|
||||
```
|
||||
Error: EACCES: permission denied
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. No read/write permission
|
||||
2. File owned by another user
|
||||
3. Directory not accessible
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check permissions
|
||||
ls -la /path/to/file
|
||||
|
||||
# Check ownership
|
||||
stat /path/to/file
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Change permissions (careful!)
|
||||
chmod 644 /path/to/file # read/write for owner, read for others
|
||||
chmod 755 /path/to/dir # execute for directories
|
||||
|
||||
# Change ownership
|
||||
sudo chown $USER:$USER /path/to/file
|
||||
|
||||
# For npm global packages
|
||||
sudo chown -R $USER /usr/local/lib/node_modules
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### EMFILE
|
||||
|
||||
```
|
||||
Error: EMFILE: too many open files
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Opening files without closing
|
||||
2. System file descriptor limit reached
|
||||
3. Watching too many files
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Check current limit
|
||||
ulimit -n
|
||||
|
||||
# Increase limit (temporary)
|
||||
ulimit -n 10000
|
||||
|
||||
# Increase limit (permanent) - add to ~/.bashrc or /etc/security/limits.conf
|
||||
# * soft nofile 10000
|
||||
# * hard nofile 10000
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Use streams for large files
|
||||
const stream = fs.createReadStream(file)
|
||||
stream.on('close', () => {
|
||||
// file handle released
|
||||
})
|
||||
|
||||
// Use graceful-fs
|
||||
const fs = require('graceful-fs')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Syntax/Parse Errors
|
||||
|
||||
### SyntaxError: Unexpected token
|
||||
|
||||
```
|
||||
SyntaxError: Unexpected token '<'
|
||||
```
|
||||
|
||||
**Common Causes by Token**:
|
||||
|
||||
| Token | Likely Cause |
|
||||
|-------|--------------|
|
||||
| `<` | HTML returned instead of JSON (API error, 404 page) |
|
||||
| `}` | Missing opening brace or extra closing |
|
||||
| `{` | Missing closing brace |
|
||||
| `)` | Missing opening parenthesis |
|
||||
| `import` | Using ESM in CommonJS context |
|
||||
| `await` | await outside async function |
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// For '<' - check API response
|
||||
const res = await fetch(url)
|
||||
console.log(res.status, await res.text()) // Debug first
|
||||
|
||||
// For import in CommonJS
|
||||
// Either use require():
|
||||
const pkg = require('package')
|
||||
|
||||
// Or add to package.json:
|
||||
{ "type": "module" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### SyntaxError: Cannot use import statement outside a module
|
||||
|
||||
```
|
||||
SyntaxError: Cannot use import statement outside a module
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
|
||||
Option 1: Use ESM
|
||||
```json
|
||||
// package.json
|
||||
{ "type": "module" }
|
||||
```
|
||||
|
||||
Option 2: Use .mjs extension
|
||||
```bash
|
||||
mv index.js index.mjs
|
||||
```
|
||||
|
||||
Option 3: Convert to CommonJS
|
||||
```javascript
|
||||
// Change
|
||||
import express from 'express'
|
||||
// To
|
||||
const express = require('express')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Type Errors
|
||||
|
||||
### TypeError: Cannot read property 'x' of undefined
|
||||
|
||||
```
|
||||
TypeError: Cannot read properties of undefined (reading 'name')
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Object is undefined/null
|
||||
2. Async operation not awaited
|
||||
3. Wrong object structure
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Optional chaining
|
||||
const name = user?.profile?.name
|
||||
|
||||
// Nullish coalescing
|
||||
const name = user?.name ?? 'default'
|
||||
|
||||
// Guard clause
|
||||
if (!user || !user.profile) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Destructuring with defaults
|
||||
const { name = 'default' } = user || {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### TypeError: x is not a function
|
||||
|
||||
```
|
||||
TypeError: callback is not a function
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Variable is not a function
|
||||
2. Import failed silently
|
||||
3. Wrong export type (default vs named)
|
||||
|
||||
**Diagnosis**:
|
||||
```javascript
|
||||
console.log(typeof callback) // Should be 'function'
|
||||
console.log(callback) // See what it actually is
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Check before calling
|
||||
if (typeof callback === 'function') {
|
||||
callback()
|
||||
}
|
||||
|
||||
// Fix import - named vs default
|
||||
// Wrong:
|
||||
import myFunc from './module' // when it's named export
|
||||
// Correct:
|
||||
import { myFunc } from './module'
|
||||
|
||||
// Or vice versa
|
||||
// Wrong:
|
||||
import { myFunc } from './module' // when it's default export
|
||||
// Correct:
|
||||
import myFunc from './module'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Async Errors
|
||||
|
||||
### UnhandledPromiseRejectionWarning
|
||||
|
||||
```
|
||||
UnhandledPromiseRejectionWarning: Error: something went wrong
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Promise rejected without .catch()
|
||||
2. async function error without try/catch
|
||||
3. Missing await
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Always handle promise rejections
|
||||
promise
|
||||
.then(result => {})
|
||||
.catch(error => console.error(error))
|
||||
|
||||
// Or use try/catch with async/await
|
||||
async function main() {
|
||||
try {
|
||||
const result = await someAsyncOperation()
|
||||
} catch (error) {
|
||||
console.error('Error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Global handler (last resort)
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
console.error('Unhandled Rejection:', reason)
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ERR_INVALID_CALLBACK
|
||||
|
||||
```
|
||||
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Passing non-function where callback expected
|
||||
2. Missing callback argument
|
||||
3. Mixing callback and promise APIs
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Wrong - mixing styles
|
||||
fs.readFile('file.txt', 'utf8') // Missing callback
|
||||
|
||||
// Correct - callback style
|
||||
fs.readFile('file.txt', 'utf8', (err, data) => {
|
||||
if (err) throw err
|
||||
console.log(data)
|
||||
})
|
||||
|
||||
// Correct - promise style
|
||||
const fs = require('fs').promises
|
||||
const data = await fs.readFile('file.txt', 'utf8')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Memory Errors
|
||||
|
||||
### JavaScript heap out of memory
|
||||
|
||||
```
|
||||
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Memory leak
|
||||
2. Processing large data in memory
|
||||
3. Infinite loop creating objects
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Increase memory limit
|
||||
node --max-old-space-size=4096 app.js
|
||||
|
||||
# For npm scripts
|
||||
NODE_OPTIONS="--max-old-space-size=4096" npm run build
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Use streams for large files
|
||||
const stream = fs.createReadStream('large-file.json')
|
||||
stream.on('data', chunk => {
|
||||
// Process chunk by chunk
|
||||
})
|
||||
|
||||
// Clear references
|
||||
let data = loadLargeData()
|
||||
processData(data)
|
||||
data = null // Allow garbage collection
|
||||
```
|
||||
|
||||
**Diagnosis**:
|
||||
```javascript
|
||||
// Monitor memory usage
|
||||
setInterval(() => {
|
||||
const used = process.memoryUsage()
|
||||
console.log(`Memory: ${Math.round(used.heapUsed / 1024 / 1024)}MB`)
|
||||
}, 5000)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Process Errors
|
||||
|
||||
### SIGTERM / SIGINT
|
||||
|
||||
```
|
||||
Process exited with SIGTERM
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Process killed externally (Ctrl+C, kill command)
|
||||
2. Container orchestrator stopping container
|
||||
3. System shutdown
|
||||
|
||||
**Solutions**:
|
||||
```javascript
|
||||
// Graceful shutdown
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('SIGTERM received, shutting down gracefully')
|
||||
server.close(() => {
|
||||
console.log('Server closed')
|
||||
process.exit(0)
|
||||
})
|
||||
})
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
console.log('SIGINT received (Ctrl+C)')
|
||||
process.exit(0)
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NPM Errors
|
||||
|
||||
### ERESOLVE unable to resolve dependency tree
|
||||
|
||||
```
|
||||
npm ERR! ERESOLVE unable to resolve dependency tree
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Peer dependency conflict
|
||||
2. Package version mismatch
|
||||
3. npm 7+ stricter resolution
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# See the conflict
|
||||
npm install --legacy-peer-deps
|
||||
|
||||
# Or force install (use carefully)
|
||||
npm install --force
|
||||
|
||||
# Better: fix the conflict
|
||||
npm ls package-name # See which versions are installed
|
||||
npm why package-name # See why it's installed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### EINTEGRITY
|
||||
|
||||
```
|
||||
npm ERR! EINTEGRITY sha512-xxx
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Corrupted cache
|
||||
2. Package modified after caching
|
||||
3. Network issues during download
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Clear npm cache
|
||||
npm cache clean --force
|
||||
|
||||
# Remove and reinstall
|
||||
rm -rf node_modules package-lock.json
|
||||
npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error Code | Category | Quick Fix |
|
||||
|------------|----------|-----------|
|
||||
| `MODULE_NOT_FOUND` | Dependency | `npm install <pkg>` |
|
||||
| `ECONNREFUSED` | Network | Start the server |
|
||||
| `ENOTFOUND` | Network | Check URL/hostname |
|
||||
| `ENOENT` | Filesystem | Check file path exists |
|
||||
| `EACCES` | Permission | `chmod` or `chown` |
|
||||
| `EMFILE` | Filesystem | Increase ulimit |
|
||||
| `heap out of memory` | Memory | `--max-old-space-size` |
|
||||
| `Unexpected token` | Syntax | Check file content type |
|
||||
| `not a function` | Type | Check import/export |
|
||||
| `ERESOLVE` | NPM | `--legacy-peer-deps` |
|
||||
@@ -0,0 +1,593 @@
|
||||
# Python Error Patterns
|
||||
|
||||
Common Python errors with diagnosis and solutions.
|
||||
|
||||
## Import Errors
|
||||
|
||||
### ModuleNotFoundError
|
||||
|
||||
```python
|
||||
ModuleNotFoundError: No module named 'package_name'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Package not installed
|
||||
2. Virtual environment not activated
|
||||
3. Wrong Python version
|
||||
4. Typo in module name
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check if package installed
|
||||
pip show package_name
|
||||
pip list | grep package
|
||||
|
||||
# Check which Python
|
||||
which python
|
||||
python --version
|
||||
|
||||
# Check if in venv
|
||||
echo $VIRTUAL_ENV
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Install package
|
||||
pip install package_name
|
||||
|
||||
# If using virtual env
|
||||
source venv/bin/activate
|
||||
pip install package_name
|
||||
|
||||
# If wrong Python version
|
||||
python3 -m pip install package_name
|
||||
pip3 install package_name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ImportError: cannot import name 'X' from 'Y'
|
||||
|
||||
```python
|
||||
ImportError: cannot import name 'MyClass' from 'mymodule'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Name doesn't exist in module
|
||||
2. Circular import
|
||||
3. Module structure changed
|
||||
4. Typo in name
|
||||
|
||||
**Diagnosis**:
|
||||
```python
|
||||
# Check what's available
|
||||
import mymodule
|
||||
print(dir(mymodule))
|
||||
|
||||
# Check if circular import
|
||||
# Add print at top of each module to see import order
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Circular import fix - move import inside function
|
||||
def my_function():
|
||||
from other_module import something
|
||||
return something()
|
||||
|
||||
# Or restructure to avoid circular dependency
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Type Errors
|
||||
|
||||
### TypeError: 'NoneType' object is not subscriptable
|
||||
|
||||
```python
|
||||
TypeError: 'NoneType' object is not subscriptable
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Function returned None (forgot return)
|
||||
2. dict.get() returned None
|
||||
3. API response is None
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Add None check
|
||||
if result is not None:
|
||||
value = result['key']
|
||||
|
||||
# Use default value
|
||||
value = result.get('key', 'default') if result else 'default'
|
||||
|
||||
# Use walrus operator (Python 3.8+)
|
||||
if (result := get_result()) is not None:
|
||||
value = result['key']
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### TypeError: 'X' object is not callable
|
||||
|
||||
```python
|
||||
TypeError: 'str' object is not callable
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Variable shadows built-in function
|
||||
2. Missing method parentheses somewhere
|
||||
3. Property accessed as method
|
||||
|
||||
**Common Culprits**:
|
||||
```python
|
||||
# Shadowing built-ins - DON'T DO THIS
|
||||
list = [1, 2, 3] # Shadows list()
|
||||
str = "hello" # Shadows str()
|
||||
dict = {'a': 1} # Shadows dict()
|
||||
type = "my_type" # Shadows type()
|
||||
id = 123 # Shadows id()
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Rename variables
|
||||
my_list = [1, 2, 3]
|
||||
my_str = "hello"
|
||||
|
||||
# Or delete the shadow
|
||||
del list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### TypeError: unsupported operand type(s)
|
||||
|
||||
```python
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Mixing types in operation
|
||||
2. Unexpected type from input/API
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Convert types explicitly
|
||||
result = str(number) + text
|
||||
result = number + int(text)
|
||||
|
||||
# Type checking
|
||||
if isinstance(value, int):
|
||||
result = value + 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Attribute Errors
|
||||
|
||||
### AttributeError: 'NoneType' object has no attribute 'X'
|
||||
|
||||
```python
|
||||
AttributeError: 'NoneType' object has no attribute 'split'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Variable is None when it shouldn't be
|
||||
2. Function returned None
|
||||
3. Failed assignment
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Guard against None
|
||||
if text is not None:
|
||||
words = text.split()
|
||||
|
||||
# With default
|
||||
words = (text or "").split()
|
||||
|
||||
# Assert early
|
||||
assert text is not None, "text cannot be None"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### AttributeError: module 'X' has no attribute 'Y'
|
||||
|
||||
```python
|
||||
AttributeError: module 'json' has no attribute 'loads'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Local file shadows standard library
|
||||
2. Wrong module imported
|
||||
3. Outdated module version
|
||||
|
||||
**Diagnosis**:
|
||||
```python
|
||||
import json
|
||||
print(json.__file__) # Check which file is loaded
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# If local file shadows stdlib
|
||||
mv json.py my_json_utils.py
|
||||
rm json.pyc __pycache__/json*
|
||||
|
||||
# Check for naming conflicts
|
||||
ls *.py | grep -E "^(json|os|sys|re|io)\.py$"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key/Index Errors
|
||||
|
||||
### KeyError
|
||||
|
||||
```python
|
||||
KeyError: 'username'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Key doesn't exist in dict
|
||||
2. Typo in key name
|
||||
3. Data structure changed
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Use .get() with default
|
||||
username = data.get('username', 'anonymous')
|
||||
|
||||
# Check before access
|
||||
if 'username' in data:
|
||||
username = data['username']
|
||||
|
||||
# Use defaultdict
|
||||
from collections import defaultdict
|
||||
data = defaultdict(str)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### IndexError: list index out of range
|
||||
|
||||
```python
|
||||
IndexError: list index out of range
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Accessing index beyond list length
|
||||
2. Empty list
|
||||
3. Off-by-one error
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Check length first
|
||||
if len(my_list) > index:
|
||||
value = my_list[index]
|
||||
|
||||
# Use try/except
|
||||
try:
|
||||
value = my_list[index]
|
||||
except IndexError:
|
||||
value = default_value
|
||||
|
||||
# Safe last element
|
||||
last = my_list[-1] if my_list else None
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Value Errors
|
||||
|
||||
### ValueError: invalid literal for int()
|
||||
|
||||
```python
|
||||
ValueError: invalid literal for int() with base 10: 'abc'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Non-numeric string to int()
|
||||
2. Float string to int()
|
||||
3. Empty string
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Safe conversion
|
||||
def safe_int(value, default=0):
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
|
||||
# Check first
|
||||
if value.isdigit():
|
||||
number = int(value)
|
||||
|
||||
# For floats as strings
|
||||
number = int(float("3.14")) # -> 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ValueError: too many values to unpack
|
||||
|
||||
```python
|
||||
ValueError: too many values to unpack (expected 2)
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Unpacking mismatch
|
||||
2. Data has more/fewer items than expected
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Use * to capture rest
|
||||
first, *rest = [1, 2, 3, 4] # first=1, rest=[2,3,4]
|
||||
first, second, *_ = [1, 2, 3, 4] # Ignore extras
|
||||
|
||||
# Check length first
|
||||
if len(items) >= 2:
|
||||
a, b = items[0], items[1]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Errors
|
||||
|
||||
### FileNotFoundError
|
||||
|
||||
```python
|
||||
FileNotFoundError: [Errno 2] No such file or directory: 'file.txt'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. File doesn't exist
|
||||
2. Wrong path (relative vs absolute)
|
||||
3. Typo in filename
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
from pathlib import Path
|
||||
|
||||
# Check existence
|
||||
path = Path('file.txt')
|
||||
if path.exists():
|
||||
content = path.read_text()
|
||||
|
||||
# Use absolute path
|
||||
path = Path(__file__).parent / 'data' / 'file.txt'
|
||||
|
||||
# Create if not exists
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.touch()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PermissionError
|
||||
|
||||
```python
|
||||
PermissionError: [Errno 13] Permission denied: '/path/to/file'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. No write permission
|
||||
2. File owned by another user
|
||||
3. File is read-only
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
ls -la /path/to/file
|
||||
stat /path/to/file
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Change permissions
|
||||
chmod 644 /path/to/file
|
||||
chmod 755 /path/to/directory
|
||||
|
||||
# Change ownership
|
||||
sudo chown $USER:$USER /path/to/file
|
||||
```
|
||||
|
||||
```python
|
||||
# Write to user directory instead
|
||||
from pathlib import Path
|
||||
user_dir = Path.home() / '.myapp'
|
||||
user_dir.mkdir(exist_ok=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Encoding Errors
|
||||
|
||||
### UnicodeDecodeError
|
||||
|
||||
```python
|
||||
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. File not UTF-8 encoded
|
||||
2. Binary file read as text
|
||||
3. Mixed encodings
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Try different encoding
|
||||
with open('file.txt', encoding='latin-1') as f:
|
||||
content = f.read()
|
||||
|
||||
# Detect encoding
|
||||
import chardet
|
||||
with open('file.txt', 'rb') as f:
|
||||
result = chardet.detect(f.read())
|
||||
encoding = result['encoding']
|
||||
|
||||
with open('file.txt', encoding=encoding) as f:
|
||||
content = f.read()
|
||||
|
||||
# Ignore errors (lossy)
|
||||
with open('file.txt', encoding='utf-8', errors='ignore') as f:
|
||||
content = f.read()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## JSON Errors
|
||||
|
||||
### json.decoder.JSONDecodeError
|
||||
|
||||
```python
|
||||
json.decoder.JSONDecodeError: Expecting value: line 1 column 1
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Invalid JSON syntax
|
||||
2. Empty string/file
|
||||
3. HTML returned instead of JSON
|
||||
|
||||
**Diagnosis**:
|
||||
```python
|
||||
# Print raw content first
|
||||
print(repr(response.text))
|
||||
print(response.text[:100])
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Check before parsing
|
||||
if response.text:
|
||||
try:
|
||||
data = json.loads(response.text)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Invalid JSON at line {e.lineno}, col {e.colno}")
|
||||
print(f"Content: {response.text[:200]}")
|
||||
|
||||
# Handle HTML error pages
|
||||
if response.text.startswith('<'):
|
||||
raise ValueError("Received HTML instead of JSON")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recursion Errors
|
||||
|
||||
### RecursionError: maximum recursion depth exceeded
|
||||
|
||||
```python
|
||||
RecursionError: maximum recursion depth exceeded
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Infinite recursion
|
||||
2. Missing base case
|
||||
3. Deep data structure
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Increase limit (temporary fix)
|
||||
import sys
|
||||
sys.setrecursionlimit(10000)
|
||||
|
||||
# Better: convert to iteration
|
||||
def factorial_iterative(n):
|
||||
result = 1
|
||||
for i in range(1, n + 1):
|
||||
result *= i
|
||||
return result
|
||||
|
||||
# Use @lru_cache for memoization
|
||||
from functools import lru_cache
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def fib(n):
|
||||
if n < 2:
|
||||
return n
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Async Errors
|
||||
|
||||
### RuntimeError: Event loop is closed
|
||||
|
||||
```python
|
||||
RuntimeError: Event loop is closed
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Trying to use closed event loop
|
||||
2. Event loop not properly managed
|
||||
3. Windows-specific issue with ProactorEventLoop
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Use asyncio.run() (Python 3.7+)
|
||||
asyncio.run(main())
|
||||
|
||||
# For Windows
|
||||
if sys.platform == 'win32':
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
|
||||
# Explicit loop management
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
loop.run_until_complete(main())
|
||||
finally:
|
||||
loop.close()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### RuntimeError: cannot reuse already awaited coroutine
|
||||
|
||||
```python
|
||||
RuntimeError: cannot reuse already awaited coroutine
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Awaiting same coroutine twice
|
||||
2. Storing coroutine in variable and reusing
|
||||
|
||||
**Solutions**:
|
||||
```python
|
||||
# Wrong - reusing coroutine
|
||||
coro = fetch_data()
|
||||
await coro
|
||||
await coro # Error!
|
||||
|
||||
# Correct - create new coroutine each time
|
||||
await fetch_data()
|
||||
await fetch_data()
|
||||
|
||||
# Or use asyncio.create_task for concurrent execution
|
||||
task1 = asyncio.create_task(fetch_data())
|
||||
task2 = asyncio.create_task(fetch_data())
|
||||
await asyncio.gather(task1, task2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| `ModuleNotFoundError` | Import | `pip install <pkg>` |
|
||||
| `ImportError: circular` | Import | Move import inside function |
|
||||
| `TypeError: NoneType subscript` | Type | Add `if x is not None` check |
|
||||
| `TypeError: not callable` | Type | Check for shadowed built-ins |
|
||||
| `AttributeError: NoneType` | Attribute | Guard against None |
|
||||
| `KeyError` | Dict | Use `.get()` with default |
|
||||
| `IndexError` | List | Check `len()` first |
|
||||
| `ValueError: int()` | Value | Use try/except |
|
||||
| `FileNotFoundError` | File | Use `Path.exists()` check |
|
||||
| `UnicodeDecodeError` | Encoding | Try `encoding='latin-1'` |
|
||||
| `JSONDecodeError` | JSON | Check response content first |
|
||||
| `RecursionError` | Recursion | Convert to iteration |
|
||||
@@ -0,0 +1,573 @@
|
||||
# React Error Patterns
|
||||
|
||||
Common React/Next.js errors with diagnosis and solutions.
|
||||
|
||||
## Hydration Errors
|
||||
|
||||
### Hydration Mismatch
|
||||
|
||||
```
|
||||
Hydration failed because the initial UI does not match what was rendered on the server.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Server and client render different content
|
||||
2. Using browser-only APIs during render
|
||||
3. Date/time formatting differences
|
||||
4. Random values in render
|
||||
|
||||
**Common Culprits**:
|
||||
```jsx
|
||||
// These cause hydration mismatch
|
||||
{new Date().toLocaleString()} // Time differs
|
||||
{Math.random()} // Random differs
|
||||
{typeof window !== 'undefined'} // Condition differs
|
||||
{localStorage.getItem('key')} // No localStorage on server
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Use useEffect for client-only code
|
||||
const [mounted, setMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
}, [])
|
||||
|
||||
if (!mounted) return null // Or return skeleton
|
||||
|
||||
return <div>{localStorage.getItem('theme')}</div>
|
||||
```
|
||||
|
||||
```jsx
|
||||
// Suppress hydration warning (last resort)
|
||||
<time suppressHydrationWarning>
|
||||
{new Date().toLocaleString()}
|
||||
</time>
|
||||
```
|
||||
|
||||
```jsx
|
||||
// Use 'use client' directive in Next.js App Router
|
||||
'use client'
|
||||
|
||||
export default function ClientComponent() {
|
||||
// Client-only code here
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Text content does not match server-rendered HTML
|
||||
|
||||
```
|
||||
Text content does not match server-rendered HTML.
|
||||
```
|
||||
|
||||
**Same as hydration mismatch** - content differs between server and client.
|
||||
|
||||
**Quick Check**:
|
||||
1. Are you using `Date`, `Math.random()`?
|
||||
2. Are you accessing `window`, `document`, `localStorage`?
|
||||
3. Are you using browser-specific formatting?
|
||||
|
||||
---
|
||||
|
||||
## Hooks Errors
|
||||
|
||||
### Invalid hook call
|
||||
|
||||
```
|
||||
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Hook called outside component
|
||||
2. Hook called in class component
|
||||
3. Hook called in regular function
|
||||
4. Multiple React versions
|
||||
5. Breaking rules of hooks
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check for multiple React versions
|
||||
npm ls react
|
||||
npm ls react-dom
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Wrong - hook in regular function
|
||||
function getData() {
|
||||
const [data, setData] = useState(null) // Error!
|
||||
}
|
||||
|
||||
// Correct - hook in component
|
||||
function MyComponent() {
|
||||
const [data, setData] = useState(null) // OK
|
||||
}
|
||||
|
||||
// Correct - custom hook
|
||||
function useData() {
|
||||
const [data, setData] = useState(null)
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Fix multiple React versions
|
||||
npm dedupe
|
||||
# Or check and align versions in package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Rendered more hooks than during previous render
|
||||
|
||||
```
|
||||
Rendered more hooks than during the previous render.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Conditional hook calls
|
||||
2. Hook inside loop
|
||||
3. Early return before all hooks
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Wrong - conditional hook
|
||||
function MyComponent({ condition }) {
|
||||
if (condition) {
|
||||
const [state, setState] = useState() // Error!
|
||||
}
|
||||
}
|
||||
|
||||
// Correct - always call hooks
|
||||
function MyComponent({ condition }) {
|
||||
const [state, setState] = useState()
|
||||
|
||||
if (!condition) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <div>{state}</div>
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
// Wrong - hook in loop
|
||||
items.forEach(item => {
|
||||
const [value, setValue] = useState() // Error!
|
||||
})
|
||||
|
||||
// Correct - use single state for all items
|
||||
const [values, setValues] = useState({})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Cannot update state on unmounted component
|
||||
|
||||
```
|
||||
Warning: Can't perform a React state update on an unmounted component.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Async operation completes after unmount
|
||||
2. Missing cleanup in useEffect
|
||||
3. Event listener not removed
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Use cleanup with flag
|
||||
useEffect(() => {
|
||||
let mounted = true
|
||||
|
||||
fetchData().then(data => {
|
||||
if (mounted) {
|
||||
setData(data)
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
mounted = false
|
||||
}
|
||||
}, [])
|
||||
```
|
||||
|
||||
```jsx
|
||||
// With AbortController
|
||||
useEffect(() => {
|
||||
const controller = new AbortController()
|
||||
|
||||
fetch(url, { signal: controller.signal })
|
||||
.then(res => res.json())
|
||||
.then(setData)
|
||||
.catch(err => {
|
||||
if (err.name !== 'AbortError') {
|
||||
setError(err)
|
||||
}
|
||||
})
|
||||
|
||||
return () => controller.abort()
|
||||
}, [url])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Errors
|
||||
|
||||
### Each child in a list should have a unique "key" prop
|
||||
|
||||
```
|
||||
Warning: Each child in a list should have a unique "key" prop.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Missing key prop in map()
|
||||
2. Using index as key (not always wrong but can cause issues)
|
||||
3. Duplicate keys
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Wrong - no key
|
||||
{items.map(item => <Item {...item} />)}
|
||||
|
||||
// Wrong - index as key (problematic if list reorders)
|
||||
{items.map((item, index) => <Item key={index} {...item} />)}
|
||||
|
||||
// Correct - unique identifier
|
||||
{items.map(item => <Item key={item.id} {...item} />)}
|
||||
|
||||
// If no ID, create stable key
|
||||
{items.map(item => <Item key={`${item.name}-${item.date}`} {...item} />)}
|
||||
```
|
||||
|
||||
**When index is OK**:
|
||||
- List is static (never reorders)
|
||||
- Items have no unique ID
|
||||
- List never re-renders
|
||||
|
||||
---
|
||||
|
||||
### Encountered two children with the same key
|
||||
|
||||
```
|
||||
Warning: Encountered two children with the same key "123".
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Duplicate IDs in data
|
||||
2. Wrong key property used
|
||||
3. Key generation produces duplicates
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Debug - find duplicates
|
||||
const keys = items.map(i => i.id)
|
||||
const duplicates = keys.filter((k, i) => keys.indexOf(k) !== i)
|
||||
console.log('Duplicates:', duplicates)
|
||||
|
||||
// Fix - combine fields for uniqueness
|
||||
{items.map((item, index) => (
|
||||
<Item key={`${item.id}-${index}`} {...item} />
|
||||
))}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Props Errors
|
||||
|
||||
### Cannot read properties of undefined (reading 'map')
|
||||
|
||||
```
|
||||
TypeError: Cannot read properties of undefined (reading 'map')
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Data not loaded yet
|
||||
2. API returned undefined
|
||||
3. Wrong prop passed
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Guard with optional chaining
|
||||
{items?.map(item => <Item key={item.id} {...item} />)}
|
||||
|
||||
// With default value
|
||||
{(items || []).map(item => <Item key={item.id} {...item} />)}
|
||||
|
||||
// Loading state
|
||||
if (!items) return <Loading />
|
||||
return items.map(item => <Item key={item.id} {...item} />)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Objects are not valid as a React child
|
||||
|
||||
```
|
||||
Objects are not valid as a React child (found: object with keys {x, y}).
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Rendering object directly instead of its properties
|
||||
2. Rendering Date object
|
||||
3. Rendering JSON object
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Wrong
|
||||
<div>{user}</div> // user is object
|
||||
<div>{new Date()}</div> // Date is object
|
||||
|
||||
// Correct
|
||||
<div>{user.name}</div>
|
||||
<div>{new Date().toLocaleDateString()}</div>
|
||||
<div>{JSON.stringify(data)}</div> // For debugging
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## useEffect Errors
|
||||
|
||||
### Maximum update depth exceeded
|
||||
|
||||
```
|
||||
Maximum update depth exceeded. This can happen when a component calls setState inside useEffect.
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Missing or wrong dependency array
|
||||
2. State update triggers re-render that triggers effect
|
||||
3. Object/array in dependency array creates infinite loop
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Wrong - missing dependency array
|
||||
useEffect(() => {
|
||||
setState(value) // Runs every render = infinite loop
|
||||
})
|
||||
|
||||
// Wrong - object in deps always "changes"
|
||||
useEffect(() => {
|
||||
// ...
|
||||
}, [{ id: 1 }]) // New object every render!
|
||||
|
||||
// Correct - stable dependency
|
||||
useEffect(() => {
|
||||
setState(value)
|
||||
}, []) // Empty = only on mount
|
||||
|
||||
// Correct - primitive dependency
|
||||
const { id } = props
|
||||
useEffect(() => {
|
||||
// ...
|
||||
}, [id]) // Primitive, stable comparison
|
||||
```
|
||||
|
||||
```jsx
|
||||
// For objects, use specific properties directly
|
||||
const { id, name } = config
|
||||
useEffect(() => {
|
||||
// use id, name
|
||||
}, [id, name])
|
||||
|
||||
// Or stringify (use sparingly, can be expensive)
|
||||
const configStr = JSON.stringify(config)
|
||||
useEffect(() => {
|
||||
// ...
|
||||
}, [configStr])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Missing dependency warning
|
||||
|
||||
```
|
||||
React Hook useEffect has a missing dependency: 'value'.
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Option 1: Add the dependency
|
||||
useEffect(() => {
|
||||
doSomething(value)
|
||||
}, [value])
|
||||
|
||||
// Option 2: Move value inside effect
|
||||
useEffect(() => {
|
||||
const value = calculateValue()
|
||||
doSomething(value)
|
||||
}, [])
|
||||
|
||||
// Option 3: Use functional update (for setState)
|
||||
useEffect(() => {
|
||||
setCount(prev => prev + 1) // No dependency on count
|
||||
}, [])
|
||||
|
||||
// Option 4: Intentionally exclude (with comment)
|
||||
useEffect(() => {
|
||||
// Only run on mount, intentionally ignoring value changes
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next.js Specific Errors
|
||||
|
||||
### Error: Invariant: headers() expects to have requestAsyncStorage
|
||||
|
||||
```
|
||||
Error: Invariant: headers() expects to have requestAsyncStorage
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Using server-only function in client component
|
||||
2. headers(), cookies() called outside request context
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Mark as server component (default in app directory)
|
||||
// Remove 'use client' if present
|
||||
|
||||
// Or fetch data in server component, pass to client
|
||||
// Server Component
|
||||
async function Page() {
|
||||
const data = await getData()
|
||||
return <ClientComponent data={data} />
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: Cannot access 'X' before initialization
|
||||
|
||||
```
|
||||
Error: Cannot access 'Component' before initialization
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Circular imports
|
||||
2. Component used before defined
|
||||
3. Import order issues
|
||||
|
||||
**Diagnosis**:
|
||||
```bash
|
||||
# Check import chain
|
||||
grep -r "import.*Component" src/
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Lazy load to break circular dependency
|
||||
const Component = dynamic(() => import('./Component'), { ssr: false })
|
||||
|
||||
// Or restructure imports
|
||||
// Move shared code to separate file
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Module not found: Can't resolve 'X'
|
||||
|
||||
```
|
||||
Module not found: Can't resolve 'fs'
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Node.js module used in client code
|
||||
2. Missing package
|
||||
3. Wrong import path
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// For Node.js modules in Next.js
|
||||
// next.config.js
|
||||
module.exports = {
|
||||
webpack: (config, { isServer }) => {
|
||||
if (!isServer) {
|
||||
config.resolve.fallback = {
|
||||
fs: false,
|
||||
path: false,
|
||||
}
|
||||
}
|
||||
return config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
// Use dynamic import with ssr: false
|
||||
const Component = dynamic(() => import('./ServerComponent'), { ssr: false })
|
||||
|
||||
// Or check environment
|
||||
if (typeof window === 'undefined') {
|
||||
// Server-only code
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build Errors
|
||||
|
||||
### Failed to compile
|
||||
|
||||
```
|
||||
Failed to compile
|
||||
./src/Component.jsx
|
||||
Module parse failed: Unexpected token
|
||||
```
|
||||
|
||||
**Common Causes**:
|
||||
1. Syntax error in code
|
||||
2. Missing babel/typescript config
|
||||
3. Unsupported syntax
|
||||
|
||||
**Check**:
|
||||
1. Look at the line number mentioned
|
||||
2. Check for unclosed brackets/quotes
|
||||
3. Verify file extension matches content
|
||||
|
||||
---
|
||||
|
||||
### Build error occurred - Cannot read property 'X' of undefined
|
||||
|
||||
```
|
||||
Build error occurred
|
||||
TypeError: Cannot read property 'map' of undefined
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Missing data during static generation
|
||||
2. API call failed during build
|
||||
3. Environment variable not set
|
||||
|
||||
**Solutions**:
|
||||
```jsx
|
||||
// Add fallback for missing data
|
||||
export async function getStaticProps() {
|
||||
try {
|
||||
const data = await fetchData()
|
||||
return { props: { data: data || [] } }
|
||||
} catch (error) {
|
||||
return { props: { data: [] } }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| Hydration mismatch | SSR | Use `useEffect` for client-only code |
|
||||
| Invalid hook call | Hooks | Check hook is in component body |
|
||||
| More hooks than previous render | Hooks | Don't use conditional hooks |
|
||||
| Unmounted component update | Async | Add cleanup/mounted flag |
|
||||
| Missing key prop | List | Add unique `key` to map items |
|
||||
| Objects not valid as child | Render | Render `obj.property` not `obj` |
|
||||
| Maximum update depth | useEffect | Check dependency array |
|
||||
| Cannot access before init | Import | Check for circular imports |
|
||||
| Module not found: fs | Build | Add webpack fallback |
|
||||
@@ -0,0 +1,572 @@
|
||||
# Rust Error Patterns
|
||||
|
||||
Common Rust errors with diagnosis and solutions.
|
||||
|
||||
## Ownership Errors
|
||||
|
||||
### cannot move out of borrowed content
|
||||
|
||||
```rust
|
||||
error[E0507]: cannot move out of borrowed content
|
||||
--> src/main.rs:5:9
|
||||
|
|
||||
5 | let s = &vec[0];
|
||||
| ^^^^^^^ cannot move out of borrowed content
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Clone if needed
|
||||
let s = vec[0].clone();
|
||||
|
||||
// Or borrow instead of move
|
||||
let s = &vec[0];
|
||||
|
||||
// Use .get() for Option
|
||||
if let Some(s) = vec.get(0) {
|
||||
// use s as reference
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### cannot borrow as mutable because it is also borrowed as immutable
|
||||
|
||||
```rust
|
||||
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
|
||||
```
|
||||
|
||||
**Causes**:
|
||||
1. Mutable and immutable borrows overlap
|
||||
2. Iterator invalidation
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Wrong
|
||||
let r1 = &vec;
|
||||
let r2 = &mut vec; // Error!
|
||||
|
||||
// Correct - end immutable borrow first
|
||||
let r1 = &vec;
|
||||
println!("{:?}", r1); // Last use of r1
|
||||
let r2 = &mut vec; // OK now
|
||||
|
||||
// For collections, use indices instead
|
||||
let len = vec.len();
|
||||
for i in 0..len {
|
||||
vec[i] += 1; // OK
|
||||
}
|
||||
|
||||
// Or use interior mutability
|
||||
use std::cell::RefCell;
|
||||
let vec = RefCell::new(vec![1, 2, 3]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### cannot borrow as mutable more than once
|
||||
|
||||
```rust
|
||||
error[E0499]: cannot borrow `x` as mutable more than once at a time
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Wrong
|
||||
let r1 = &mut vec;
|
||||
let r2 = &mut vec; // Error!
|
||||
|
||||
// Correct - scope the first borrow
|
||||
{
|
||||
let r1 = &mut vec;
|
||||
// use r1
|
||||
} // r1 goes out of scope
|
||||
let r2 = &mut vec; // OK now
|
||||
|
||||
// Or use split_at_mut for slices
|
||||
let (left, right) = slice.split_at_mut(mid);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### value borrowed here after move
|
||||
|
||||
```rust
|
||||
error[E0382]: borrow of moved value: `s`
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Wrong
|
||||
let s = String::from("hello");
|
||||
let s2 = s;
|
||||
println!("{}", s); // Error! s was moved
|
||||
|
||||
// Option 1: Clone
|
||||
let s = String::from("hello");
|
||||
let s2 = s.clone();
|
||||
println!("{}", s); // OK
|
||||
|
||||
// Option 2: Use references
|
||||
let s = String::from("hello");
|
||||
let s2 = &s;
|
||||
println!("{}", s); // OK
|
||||
|
||||
// Option 3: Copy types (implement Copy)
|
||||
let x = 5;
|
||||
let y = x;
|
||||
println!("{}", x); // OK, i32 is Copy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Lifetime Errors
|
||||
|
||||
### missing lifetime specifier
|
||||
|
||||
```rust
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> src/main.rs:1:17
|
||||
|
|
||||
1 | fn longest(x: &str, y: &str) -> &str {
|
||||
| ---- ---- ^ expected named lifetime parameter
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Add lifetime annotation
|
||||
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
|
||||
if x.len() > y.len() { x } else { y }
|
||||
}
|
||||
|
||||
// For structs holding references
|
||||
struct Parser<'a> {
|
||||
input: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
fn new(input: &'a str) -> Self {
|
||||
Parser { input }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### lifetime may not live long enough
|
||||
|
||||
```rust
|
||||
error: lifetime may not live long enough
|
||||
--> src/main.rs:3:5
|
||||
|
|
||||
2 | fn example<'a>(x: &'a str) -> &'static str {
|
||||
| -- lifetime `'a` defined here
|
||||
3 | x
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Match lifetimes correctly
|
||||
fn example<'a>(x: &'a str) -> &'a str {
|
||||
x
|
||||
}
|
||||
|
||||
// Or convert to owned type
|
||||
fn example(x: &str) -> String {
|
||||
x.to_string()
|
||||
}
|
||||
|
||||
// Use 'static only for actual static data
|
||||
fn example() -> &'static str {
|
||||
"literal string" // String literals are 'static
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Type Errors
|
||||
|
||||
### mismatched types
|
||||
|
||||
```rust
|
||||
error[E0308]: mismatched types
|
||||
--> src/main.rs:3:20
|
||||
|
|
||||
3 | let x: i32 = "hello";
|
||||
| --- ^^^^^^^ expected `i32`, found `&str`
|
||||
| |
|
||||
| expected due to this
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Parse strings to numbers
|
||||
let x: i32 = "42".parse().unwrap();
|
||||
// Or with error handling
|
||||
let x: i32 = "42".parse()?;
|
||||
|
||||
// Convert between numeric types
|
||||
let x: i32 = 42;
|
||||
let y: i64 = x as i64;
|
||||
let z: i64 = x.into(); // If From trait implemented
|
||||
|
||||
// Convert to String
|
||||
let s = x.to_string();
|
||||
let s = format!("{}", x);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### the trait bound is not satisfied
|
||||
|
||||
```rust
|
||||
error[E0277]: the trait bound `MyType: Debug` is not satisfied
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Derive the trait
|
||||
#[derive(Debug)]
|
||||
struct MyType {
|
||||
field: i32,
|
||||
}
|
||||
|
||||
// Or implement manually
|
||||
impl std::fmt::Debug for MyType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "MyType {{ field: {} }}", self.field)
|
||||
}
|
||||
}
|
||||
|
||||
// Common derivable traits
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||
struct MyType {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### cannot find type/value in this scope
|
||||
|
||||
```rust
|
||||
error[E0412]: cannot find type `MyType` in this scope
|
||||
error[E0425]: cannot find value `my_var` in this scope
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Import from module
|
||||
use my_module::MyType;
|
||||
|
||||
// Or use full path
|
||||
let x = my_module::MyType::new();
|
||||
|
||||
// For std types
|
||||
use std::collections::HashMap;
|
||||
|
||||
// Check visibility - pub needed for external use
|
||||
pub struct MyType; // Visible outside module
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Option/Result Errors
|
||||
|
||||
### cannot use `?` operator on Option in function that returns Result
|
||||
|
||||
```rust
|
||||
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option`
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Match return types
|
||||
fn example() -> Option<i32> {
|
||||
let x = some_option()?; // OK
|
||||
Some(x)
|
||||
}
|
||||
|
||||
fn example() -> Result<i32, Error> {
|
||||
let x = some_result()?; // OK
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
// Convert Option to Result
|
||||
fn example() -> Result<i32, &'static str> {
|
||||
let x = some_option().ok_or("value was None")?;
|
||||
Ok(x)
|
||||
}
|
||||
|
||||
// Convert Result to Option
|
||||
fn example() -> Option<i32> {
|
||||
let x = some_result().ok()?;
|
||||
Some(x)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### called `unwrap()` on a `None` value / `Err` value
|
||||
|
||||
```rust
|
||||
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value'
|
||||
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ...'
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Use pattern matching
|
||||
match option {
|
||||
Some(value) => println!("{}", value),
|
||||
None => println!("No value"),
|
||||
}
|
||||
|
||||
// Use if let
|
||||
if let Some(value) = option {
|
||||
println!("{}", value);
|
||||
}
|
||||
|
||||
// Use unwrap_or for defaults
|
||||
let value = option.unwrap_or(default);
|
||||
let value = option.unwrap_or_else(|| compute_default());
|
||||
|
||||
// Use ? for propagation
|
||||
let value = option?; // Returns None if None
|
||||
let value = result?; // Returns Err if Err
|
||||
|
||||
// Use expect for better panic messages
|
||||
let value = option.expect("option should have a value here");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Concurrency Errors
|
||||
|
||||
### cannot be sent between threads safely
|
||||
|
||||
```rust
|
||||
error[E0277]: `Rc<T>` cannot be sent between threads safely
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Use Arc instead of Rc for threads
|
||||
use std::sync::Arc;
|
||||
let data = Arc::new(vec![1, 2, 3]);
|
||||
let data_clone = Arc::clone(&data);
|
||||
|
||||
std::thread::spawn(move || {
|
||||
println!("{:?}", data_clone);
|
||||
});
|
||||
|
||||
// For mutation, use Arc<Mutex<T>>
|
||||
use std::sync::{Arc, Mutex};
|
||||
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
|
||||
|
||||
let data_clone = Arc::clone(&data);
|
||||
std::thread::spawn(move || {
|
||||
let mut guard = data_clone.lock().unwrap();
|
||||
guard.push(4);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### cannot be shared between threads safely
|
||||
|
||||
```rust
|
||||
error[E0277]: `RefCell<T>` cannot be shared between threads safely
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Use Mutex or RwLock instead of RefCell
|
||||
use std::sync::Mutex;
|
||||
let data = Mutex::new(0);
|
||||
|
||||
// Multiple readers, single writer
|
||||
use std::sync::RwLock;
|
||||
let data = RwLock::new(0);
|
||||
|
||||
// Read
|
||||
let value = *data.read().unwrap();
|
||||
|
||||
// Write
|
||||
*data.write().unwrap() = 42;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### closure may outlive the current function
|
||||
|
||||
```rust
|
||||
error[E0373]: closure may outlive the current function, but it borrows `x`
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Use move to take ownership
|
||||
let x = String::from("hello");
|
||||
let closure = move || {
|
||||
println!("{}", x);
|
||||
};
|
||||
|
||||
// For threads
|
||||
let x = String::from("hello");
|
||||
std::thread::spawn(move || {
|
||||
println!("{}", x);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Macro Errors
|
||||
|
||||
### no rules expected this token
|
||||
|
||||
```rust
|
||||
error: no rules expected the token `)`
|
||||
--> src/main.rs:5:10
|
||||
|
|
||||
5 | vec![,];
|
||||
| ^ no rules expected this token in macro call
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Check macro syntax
|
||||
vec![] // Empty vector
|
||||
vec![1, 2, 3] // With elements
|
||||
vec![0; 5] // 5 zeros
|
||||
|
||||
// For custom macros, check pattern matching
|
||||
macro_rules! my_macro {
|
||||
($($x:expr),*) => { ... }; // Comma separated
|
||||
($($x:expr),+ $(,)?) => { ... }; // With trailing comma
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Async Errors
|
||||
|
||||
### future cannot be sent between threads safely
|
||||
|
||||
```rust
|
||||
error: future cannot be sent between threads safely
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Use Send-safe types
|
||||
// Arc instead of Rc
|
||||
// Mutex instead of RefCell
|
||||
|
||||
// Avoid holding non-Send types across await
|
||||
{
|
||||
let guard = mutex.lock().unwrap();
|
||||
// use guard
|
||||
} // Drop before await
|
||||
async_operation().await;
|
||||
|
||||
// Use spawn_local for non-Send futures
|
||||
tokio::task::spawn_local(async move {
|
||||
// Can use non-Send types here
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `await` is only allowed inside `async` functions
|
||||
|
||||
```rust
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Mark function as async
|
||||
async fn example() {
|
||||
some_async_fn().await;
|
||||
}
|
||||
|
||||
// Or use async block
|
||||
fn example() -> impl Future<Output = ()> {
|
||||
async {
|
||||
some_async_fn().await;
|
||||
}
|
||||
}
|
||||
|
||||
// In main, use runtime
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
example().await;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build Errors
|
||||
|
||||
### unresolved import
|
||||
|
||||
```rust
|
||||
error[E0432]: unresolved import `crate::module`
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```rust
|
||||
// Check module structure
|
||||
// src/lib.rs or src/main.rs
|
||||
mod my_module; // Declares module
|
||||
|
||||
// src/my_module.rs or src/my_module/mod.rs
|
||||
pub fn my_function() {}
|
||||
|
||||
// Then import
|
||||
use crate::my_module::my_function;
|
||||
|
||||
// For external crates, add to Cargo.toml
|
||||
[dependencies]
|
||||
serde = "1.0"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### use of undeclared crate or module
|
||||
|
||||
```rust
|
||||
error[E0433]: failed to resolve: use of undeclared crate or module `tokio`
|
||||
```
|
||||
|
||||
**Solutions**:
|
||||
```toml
|
||||
# Add to Cargo.toml
|
||||
[dependencies]
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
```
|
||||
|
||||
```bash
|
||||
# Then run
|
||||
cargo build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Error | Category | Quick Fix |
|
||||
|-------|----------|-----------|
|
||||
| cannot move out of borrowed | Ownership | Clone or use reference |
|
||||
| cannot borrow as mutable | Borrow | End previous borrow first |
|
||||
| value borrowed after move | Move | Clone or use reference |
|
||||
| missing lifetime specifier | Lifetime | Add `<'a>` annotation |
|
||||
| mismatched types | Type | Use conversion methods |
|
||||
| trait bound not satisfied | Trait | Derive or implement trait |
|
||||
| `?` operator wrong return | Error | Match return type |
|
||||
| unwrap on None/Err | Error | Use `?` or pattern match |
|
||||
| cannot be sent between threads | Concurrency | Use Arc/Mutex |
|
||||
| closure may outlive | Closure | Add `move` keyword |
|
||||
| unresolved import | Module | Check mod declaration |
|
||||
Reference in New Issue
Block a user