bookworm-smart-assistant/skills/debugger-expert/references/common-errors.md

442 lines
10 KiB
Markdown
Raw Normal View History

# 常见错误速查与修复方案 (Common Errors Reference)
> 格式:错误信息 -> 常见原因 -> 修复命令/代码
---
## 一、CORS 错误
### 错误信息
```
Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present.
```
### 常见原因
- 后端未配置 CORS 响应头
- 预检请求 (OPTIONS) 未正确处理
- 允许的 Origin 列表遗漏了前端地址
- Nginx 反代层未透传 CORS 头
### 修复方案
**Nginx 配置**
```nginx
server {
location /api/ {
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '$http_origin';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 86400;
return 204;
}
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
proxy_pass http://backend:8000;
}
}
```
**Express 配置**
```typescript
import cors from 'cors';
app.use(cors({
origin: ['http://localhost:3000', 'https://yourdomain.com'],
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
}));
```
**FastAPI 配置**
```python
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000", "https://yourdomain.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
```
---
## 二、React Hydration 错误
### 错误信息
```
Hydration failed because the initial UI does not match what was rendered on the server.
```
### 常见触发场景
- 使用 `Date.now()``Math.random()` 等在服务端和客户端产生不同值的表达式
- 根据 `window` / `localStorage` 条件渲染内容
- 嵌套了无效的 HTML 结构(如 `<p>` 内嵌 `<div>`
- 浏览器扩展注入了额外的 DOM 节点
### 修复方案
```tsx
// 方案1使用 useEffect 延迟客户端渲染
function ClientOnlyTime() {
const [time, setTime] = useState<string>('');
useEffect(() => {
setTime(new Date().toLocaleString());
}, []);
return <span>{time || '--'}</span>; // 服务端渲染占位符
}
// 方案2使用 suppressHydrationWarning
<time dateTime={dateString} suppressHydrationWarning>
{formattedDate}
</time>
// 方案3使用 next/dynamic 禁用 SSR
import dynamic from 'next/dynamic';
const BrowserOnlyChart = dynamic(() => import('./Chart'), { ssr: false });
```
---
## 三、Next.js 常见错误
### 3.1 "use client" 边界错误
```
Error: You're importing a component that needs useState. It only works in a
Client Component but none of its parents are marked with "use client".
```
**修复**:在使用 React hooks 的组件文件顶部添加 `"use client";`
```tsx
"use client"; // 必须是文件的第一行
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
```
### 3.2 Server/Client 组件混用
```
Error: Functions cannot be passed directly to Client Components unless you
explicitly expose it by marking it with "use server".
```
**修复**:不要将函数 prop 从 Server Component 传给 Client Component改用 Server Actions
```tsx
// app/actions.ts
"use server";
export async function submitForm(data: FormData) {
// 服务端逻辑
}
// app/page.tsx (Server Component)
import { submitForm } from './actions';
import ClientForm from './ClientForm';
export default function Page() {
return <ClientForm action={submitForm} />;
}
```
### 3.3 Dynamic Import 问题
```
Error: Element type is invalid: expected a string or a class/function but got: undefined
```
**修复**:确认 dynamic import 的组件使用了 default export
```tsx
// 确保组件使用 default export
const DynamicComponent = dynamic(() => import('./MyComponent'), {
loading: () => <p>加载中...</p>,
ssr: false, // 如果组件依赖浏览器 API
});
```
---
## 四、Prisma/ORM 错误
### 4.1 Connection Pool Exhaustion
```
Error: Timed out fetching a new connection from the connection pool.
```
**修复**
```prisma
// schema.prisma - 调整连接池
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// 连接字符串中设置池大小
// DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=20&pool_timeout=10"
```
```typescript
// 确保 Prisma Client 为单例
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma = globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
```
### 4.2 Migration Drift
```
Error: The current database is not managed by Prisma Migrate.
```
**修复**
```bash
# 重置迁移历史(开发环境)
npx prisma migrate reset
# 将现有数据库与 schema 对齐
npx prisma db pull # 从数据库生成 schema
npx prisma migrate dev # 生成新迁移
```
### 4.3 类型不匹配
```
Error: Argument of type 'string' is not assignable to parameter of type 'number'.
```
**修复**:运行 `npx prisma generate` 重新生成类型,确保 schema 和代码类型一致。
---
## 五、PostgreSQL 错误
### 5.1 连接超时
```
Error: connect ETIMEDOUT / Connection refused
```
**排查步骤**
```bash
# 检查 PostgreSQL 是否在运行
sudo systemctl status postgresql
# 或 Docker 环境
docker ps | grep postgres
# 检查监听端口
ss -tlnp | grep 5432
# 检查 pg_hba.conf 是否允许远程连接
# host all all 0.0.0.0/0 md5
# 检查 postgresql.conf
# listen_addresses = '*'
# 测试连接
psql -h localhost -U myuser -d mydb -c "SELECT 1;"
```
### 5.2 死锁检测
```
ERROR: deadlock detected
DETAIL: Process 1234 waits for ShareLock on transaction 5678;
blocked by process 9012.
```
**排查与修复**
```sql
-- 查看当前锁等待
SELECT pid, usename, query, state, wait_event_type, wait_event
FROM pg_stat_activity
WHERE state = 'active' AND wait_event IS NOT NULL;
-- 查看锁冲突
SELECT blocked.pid AS blocked_pid,
blocking.pid AS blocking_pid,
blocked.query AS blocked_query
FROM pg_catalog.pg_locks blocked
JOIN pg_catalog.pg_locks blocking
ON blocking.locktype = blocked.locktype
AND blocking.relation = blocked.relation
AND blocking.pid != blocked.pid
WHERE NOT blocked.granted;
-- 终止阻塞进程(谨慎使用)
SELECT pg_terminate_backend(<blocking_pid>);
```
### 5.3 索引失效
**常见原因**对列使用了函数、隐式类型转换、LIKE '%前缀'
```sql
-- 错误:函数导致索引失效
SELECT * FROM users WHERE LOWER(email) = 'test@example.com';
-- 修复:创建表达式索引
CREATE INDEX idx_users_email_lower ON users (LOWER(email));
-- 检查查询是否使用了索引
EXPLAIN ANALYZE SELECT * FROM users WHERE LOWER(email) = 'test@example.com';
```
---
## 六、Docker 错误
### 6.1 端口冲突
```
Error: Bind for 0.0.0.0:3000 failed: port is already allocated
```
**修复**
```bash
# 查找占用端口的进程
# Linux/Mac
lsof -i :3000
# Windows
netstat -ano | findstr :3000
# 停止占用端口的容器
docker ps | grep 3000
docker stop <container_id>
# 或更换端口映射
docker run -p 3001:3000 myapp
```
### 6.2 权限问题
```
Error: EACCES: permission denied
```
**修复**
```dockerfile
# Dockerfile 中设置正确的用户
RUN addgroup --system app && adduser --system --ingroup app app
RUN chown -R app:app /app
USER app
```
### 6.3 网络不通
```
Error: Could not resolve host / Connection refused between containers
```
**修复**
```yaml
# docker-compose.yml - 确保服务在同一网络
services:
app:
networks:
- backend
depends_on:
- db
db:
networks:
- backend
networks:
backend:
driver: bridge
# 容器间使用服务名访问,不要使用 localhost
# DATABASE_URL=postgresql://user:pass@db:5432/mydb
```
### 6.4 构建缓存失效
```bash
# 强制重新构建(不使用缓存)
docker compose build --no-cache
# 清理悬空镜像和构建缓存
docker system prune -f
docker builder prune -f
# 优化 Dockerfile 层顺序以利用缓存
# 把不常变化的放前面(安装依赖),常变化的放后面(复制代码)
```
---
## 七、Git 错误
### 7.1 Merge Conflict
```
CONFLICT (content): Merge conflict in src/app.ts
Automatic merge failed; fix conflicts and then commit the result.
```
**修复**
```bash
# 查看冲突文件
git status
# 手动编辑冲突文件,选择保留的代码
# 删除 <<<<<<<, =======, >>>>>>> 标记
# 标记为已解决
git add src/app.ts
git commit -m "resolve merge conflict in app.ts"
# 或放弃合并
git merge --abort
```
### 7.2 Detached HEAD
```
You are in 'detached HEAD' state.
```
**修复**
```bash
# 查看当前位置
git log --oneline -5
# 创建新分支保存当前改动
git checkout -b my-fix-branch
# 或回到原来的分支
git checkout main
```
### 7.3 大文件推送失败
```
remote: error: File large-file.zip is 150.00 MB; this exceeds the 100 MB limit.
```
**修复**
```bash
# 从历史中移除大文件
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch large-file.zip' HEAD
# 使用 Git LFS 管理大文件
git lfs install
git lfs track "*.zip"
git add .gitattributes
git add large-file.zip
git commit -m "track large files with LFS"
# 添加 .gitignore 防止再次提交
echo "*.zip" >> .gitignore
```