返回顶部
e

error-handling错误处理

Error handling patterns across languages and layers — operational vs programmer errors, retry strategies, circuit breakers, error boundaries, HTTP responses, graceful degradation, and structured logging. Use when designing error strategies, building resilient APIs, or reviewing error management.

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 1.0.0
安全检测
已通过
1,370
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

error-handling

错误处理模式

交付健壮的软件。在边界处处理错误,快速且响亮地失败,绝不静默吞没异常。

错误处理哲学

原则描述
快速失败尽早检测错误——在边界处验证输入,而非深入业务逻辑
响亮失败
错误必须可见——记录它们、暴露它们、针对它们发出告警 | | 在边界处处理 | 在层边界(控制器、中间件、网关)捕获并转换错误 | | 让它崩溃 | 对于不可恢复的状态,崩溃并重启(Erlang/OTP 哲学) | | 具体明确 | 捕获特定的错误类型,绝不使用裸 catch 或 except | | 提供上下文 | 每个错误携带足够的上下文,无需复现即可诊断 |

错误类型

操作性错误 — 网络超时、无效的用户输入、文件未找到、数据库连接丢失。优雅处理。

程序员错误 — TypeError、空引用、断言失败。修复代码——不要捕获并压制。

javascript
// 操作性错误 — 优雅处理
try {
const data = await fetch(/api/users);
} catch (err) {
if (err.code === ECONNREFUSED) return fallbackData;
throw err; // 重新抛出意外错误
}

// 程序员错误 — 让它崩溃,修复 bug
const user = null;
user.name; // TypeError — 不要用 try/catch 捕获这个



语言模式


语言机制反模式
JavaScripttry/catch、Promise.catch、Error 子类.catch(() => {}) 吞没错误
Python
异常、上下文管理器(with) | 裸 except: 捕获所有异常 |
| Go | error 返回、errors.Is/As、fmt.Errorf 包装 | _ = riskyFunction() 忽略错误 |
| Rust | Result、Option、? 运算符 | 生产代码中使用 .unwrap() |

JavaScript — 错误子类

javascript
class AppError extends Error {
constructor(message, code, statusCode, details = {}) {
super(message);
this.name = this.constructor.name;
this.code = code;
this.statusCode = statusCode;
this.details = details;
this.isOperational = true;
}
}

class NotFoundError extends AppError {
constructor(resource, id) {
super(${resource} 未找到, NOT_FOUND, 404, { resource, id });
}
}

class ValidationError extends AppError {
constructor(errors) {
super(验证失败, VALIDATION_ERROR, 422, { errors });
}
}

Go — 错误包装

go
func GetUser(id string) (*User, error) {
row := db.QueryRow(SELECT * FROM users WHERE id = $1, id)
var user User
if err := row.Scan(&user.ID, &user.Name); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf(用户 %s: %w, id, ErrNotFound)
}
return nil, fmt.Errorf(查询用户 %s: %w, id, err)
}
return &user, nil
}



错误边界

Express 错误中间件

javascript
app.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
const response = {
error: {
code: err.code || INTERNAL_ERROR,
message: err.isOperational ? err.message : 出了点问题,
...(process.env.NODE_ENV === development && { stack: err.stack }),
requestId: req.id,
},
};

logger.error(请求失败, {
err, requestId: req.id, method: req.method, path: req.path,
});

res.status(statusCode).json(response);
});

React 错误边界

tsx
import { ErrorBoundary } from react-error-boundary;

function ErrorFallback({ error, resetErrorBoundary }) {
return (


出了点问题


{error.message}



);
}

queryClient.clear()}>




重试模式


模式何时使用配置
指数退避瞬时故障(网络、503)基础 1s,最大 30s,因子 2x
退避 + 抖动
多个客户端重试 | 每次延迟随机 ±30% |
| 断路器 | 下游服务持续失败 | 5 次失败后断开,30s 后半开 |
| 隔板 | 隔离故障以防止级联 | 限制每个服务的并发调用数 |
| 超时 | 防止无限挂起 | 连接 5s,读取 30s,总计 60s |

带抖动的指数退避

javascript
async function withRetry(fn, { maxRetries = 3, baseDelay = 1000, maxDelay = 30000 } = {}) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxRetries || !isRetryable(err)) throw err;
const delay = Math.min(baseDelay 2 * attempt, maxDelay);
const jitter = delay (0.7 + Math.random() 0.6);
await new Promise((r) => setTimeout(r, jitter));
}
}
}

function isRetryable(err) {
return [408, 429, 500, 502, 503, 504].includes(err.statusCode) || err.code === ECONNRESET;
}

断路器

javascript
class CircuitBreaker {
constructor({ threshold = 5, resetTimeout = 30000 } = {}) {
this.state = CLOSED; // CLOSED → OPEN → HALF_OPEN → CLOSED
this.failureCount = 0;
this.threshold = threshold;
this.resetTimeout = resetTimeout;
this.nextAttempt = 0;
}

async call(fn) {
if (this.state === OPEN) {
if (Date.now() < this.nextAttempt) throw new Error(断路器已断开);
this.state = HALF_OPEN;
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (err) {
this.onFailure();
throw err;
}
}

onSuccess() { this.failureCount = 0; this.state = CLOSED; }
onFailure() {
this.failureCount++;
if (this.failureCount >= this.threshold) {
this.state = OPEN;
this.nextAttempt = Date.now() + this.resetTimeout;
}
}
}



HTTP 错误响应


状态码名称何时使用
400错误请求语法错误、无效 JSON
401
未授权 | 缺少或无效的身份验证 |
| 403 | 禁止访问 | 已认证但权限不足 |
| 404 | 未找到 | 资源不存在 |
| 409 | 冲突 | 请求与当前状态冲突 |
| 422 | 不可处理的实体 | 语法正确但语义错误 |
| 429 | 请求过多 | 超出速率限制(包含 Retry-After) |
| 500 | 内部服务器错误 | 意外的服务器故障 |
| 502 | 错误网关 | 上游返回无效响应 |
| 503 | 服务不可用 | 临时过载或维护中 |

标准错误信封

json
{
error: {
code: VALIDATION_ERROR,
message: 请求体包含无效字段。,
details: [
{ field: email, message: 必须是有效的电子邮件地址 }
],
requestId: req_abc123xyz
}
}



优雅降级


策略示例
回退值当图片服务不可用时显示缓存的头像
功能开关
禁用不稳定的推荐引擎 |
| 缓存响应 | 使用 X-Cache: STALE 头提供过期数据 |
| 部分响应 | 返回可用数据并附带 warnings 数组 |

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 api-error-handling-1776419943 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 api-error-handling-1776419943 技能

通过命令行安装

skillhub install api-error-handling-1776419943

下载

⬇ 下载 error-handling v1.0.0(免费)

文件大小: 6.08 KB | 发布时间: 2026-4-17 19:52

v1.0.0 最新 2026-4-17 19:52
Initial release — comprehensive guide to error handling patterns across languages and system layers.

- Details operational vs programmer errors and how to handle each.
- Provides code examples for JavaScript, Python, Go, and Rust error handling best practices.
- Includes error boundaries for Express (Node.js) and React.
- Describes structured error responses for HTTP APIs and recommended status codes.
- Outlines retry, backoff, circuit breaker, and graceful degradation strategies.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部