error-handling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseError Handling
错误处理
Quick Start
快速开始
When handling errors:
- Never expose technical details to users
- Log errors server-side with context
- Provide user-friendly error messages
- Use appropriate HTTP status codes
- Implement error recovery when possible
处理错误时需遵循以下原则:
- 永远不要向用户暴露技术细节
- 在服务端记录带上下文的错误日志
- 提供对用户友好的错误提示
- 使用合适的HTTP状态码
- 尽可能实现错误恢复
Common Patterns
常见模式
API Error Handling
API错误处理
typescript
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
// Business logic
const result = await processRequest();
return NextResponse.json(result);
} catch (error) {
// Log error with context
console.error('API Error:', {
endpoint: '/api/example',
error: error.message,
stack: error.stack,
timestamp: new Date().toISOString(),
});
// Return user-friendly error
return NextResponse.json(
{ error: 'Ha ocurrido un error. Por favor, intenta nuevamente.' },
{ status: 500 }
);
}
}typescript
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
// Business logic
const result = await processRequest();
return NextResponse.json(result);
} catch (error) {
// Log error with context
console.error('API Error:', {
endpoint: '/api/example',
error: error.message,
stack: error.stack,
timestamp: new Date().toISOString(),
});
// Return user-friendly error
return NextResponse.json(
{ error: 'Ha ocurrido un error. Por favor, intenta nuevamente.' },
{ status: 500 }
);
}
}Validation Errors
验证错误
typescript
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
name: z.string().min(1),
});
try {
const data = schema.parse(requestBody);
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{
error: 'Datos inválidos',
details: error.errors.map(e => ({
field: e.path.join('.'),
message: e.message,
}))
},
{ status: 400 }
);
}
}typescript
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
name: z.string().min(1),
});
try {
const data = schema.parse(requestBody);
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{
error: 'Datos inválidos',
details: error.errors.map(e => ({
field: e.path.join('.'),
message: e.message,
}))
},
{ status: 400 }
);
}
}Component Error Handling
组件错误处理
typescript
'use client';
import { useState } from 'react';
function ProductCard({ product }: ProductCardProps) {
const [error, setError] = useState<string | null>(null);
const handleAddToCart = async () => {
try {
setError(null);
await addToCart(product.id);
} catch (error) {
setError('No se pudo agregar el producto al carrito');
console.error('Add to cart error:', error);
}
};
return (
<div>
{error && (
<div className="text-red-500 text-sm">{error}</div>
)}
<Button onClick={handleAddToCart}>Agregar</Button>
</div>
);
}typescript
'use client';
import { useState } from 'react';
function ProductCard({ product }: ProductCardProps) {
const [error, setError] = useState<string | null>(null);
const handleAddToCart = async () => {
try {
setError(null);
await addToCart(product.id);
} catch (error) {
setError('No se pudo agregar el producto al carrito');
console.error('Add to cart error:', error);
}
};
return (
<div>
{error && (
<div className="text-red-500 text-sm">{error}</div>
)}
<Button onClick={handleAddToCart}>Agregar</Button>
</div>
);
}Error Boundary
Error Boundary
typescript
'use client';
import { ErrorBoundary } from 'react-error-boundary';
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert" className="p-4 border border-red-300 rounded">
<h2>Algo salió mal</h2>
<p>{error.message}</p>
<Button onClick={resetErrorBoundary}>Intentar de nuevo</Button>
</div>
);
}
function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<YourComponent />
</ErrorBoundary>
);
}typescript
'use client';
import { ErrorBoundary } from 'react-error-boundary';
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert" className="p-4 border border-red-300 rounded">
<h2>Algo salió mal</h2>
<p>{error.message}</p>
<Button onClick={resetErrorBoundary}>Intentar de nuevo</Button>
</div>
);
}
function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<YourComponent />
</ErrorBoundary>
);
}Error Types
错误类型
- 400 Bad Request: Invalid input
- 401 Unauthorized: Not authenticated
- 403 Forbidden: Not authorized
- 404 Not Found: Resource doesn't exist
- 500 Internal Server Error: Server error
- 503 Service Unavailable: Service down
- 400 Bad Request:无效输入
- 401 Unauthorized:未认证
- 403 Forbidden:无访问权限
- 404 Not Found:资源不存在
- 500 Internal Server Error:服务端错误
- 503 Service Unavailable:服务不可用
Best Practices
最佳实践
- Log errors with full context
- Never expose stack traces to users
- Provide actionable error messages
- Implement retry logic for transient errors
- Use error boundaries for React components
- 记录带完整上下文的错误日志
- 永远不要向用户暴露栈追踪信息
- 提供可执行的错误提示指引
- 为瞬时错误实现重试逻辑
- 为React组件使用Error Boundary