← ClaudeAtlas

error-handlinglisted

处理错误与异常时使用。不吞异常、不裸抛、给出可恢复信息。
Wade-DevCode/awesome-coding-skills-cn · ★ 3 · AI & Automation · score 78
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# 错误处理 ## 何时用 - 写任何涉及 IO、网络、数据库、外部 SDK 调用的代码时。 - 在函数/方法中加 try-catch/try-except,需要确定该怎么处理时。 - 联调时前端反馈"不知道哪里出错了"或日志里找不到报错原因时。 - code review 发现 catch 块为空、或者只有 `console.log(e)` 时。 ## 核心规则 ### 1. 不吞异常:catch 块必须有实质处理 **规则:** `catch`/`except` 块里必须有真正的处理动作——记录日志、触发回滚、重新抛出或转换为业务错误;禁止空 catch 块,禁止仅打印后继续正常流程假装没发生过。 **为什么:** AI 生成代码时,"先写个 try-catch 让它跑起来"是最常见的反模式——`catch (e) {}` 或 `except: pass`。空 catch 会把真实的数据库连接失败、磁盘写入错误、第三方 API 超时全部静默吞掉,函数返回"成功",上层完全感知不到异常,日志里没有任何线索,用户看到的是数据没有保存但页面显示"操作成功"。定位这类 bug 通常要花几倍时间,因为所有的证据都被主动销毁了。 **怎么做:** - 能处理就处理(重试、降级、返回默认值),并记录 warn 级日志。 - 不能处理就重新抛出(`throw`/`raise`),让上层决定。 - 需要转换语义时,把底层异常包裹成业务异常再抛:`throw new PaymentFailedException("支付网关超时", cause=e)`。 - `finally` 块做资源清理,不要把清理逻辑写在 catch 里然后 return 提前跳出。 --- ### 2. 错误分类:可预期错误与意外错误分开处理 **规则:** 明确区分两类错误——可预期的业务错误(用户输入非法、资源不存在、权限不足)和意外的系统错误(空指针、数据库宕机、bug);前者用业务异常类表达,后者进入全局 handler 并触发告警。 **为什么:** AI 生成的代码经常把所有异常一律 `catch (Exception e)` 然后返回 500——校验失败返回 500、资源不存在返回 500、真正的 bug 也是 500。监控告警全是噪音,用户看到的错误信息毫无意义,oncall 工程师不知道哪些 500 需要紧急处理、哪些是正常的业务错误被错误分类了。错误分类是可观测性的基础,混在一起会让整个告警体系失效。 **怎么做:** ```python # 业务异常基类(可预期,映射到 4xx) class AppError(Exception): def __init__(self, code: str, message: str, http_status: int = 400): self.code = code self.message = message self.http_status = http_status class ResourceNotFoundError(AppError): def __init__(self, resource: str, resource_id): super().__init__("RESOURCE_NOT_FOUND", f"{resource} {resource_id} 不存在", 404) # 意外错误不捕获,让全局 ha