关于 python-error-handling
python-error-handling 是面向 Python 开发者的错误处理技能,涵盖输入校验、异常设计和失败恢复。重点包括保留调试上下文,以及在批处理中处理部分失败。
主要功能
- 01提前校验输入
- 02设计有上下文的异常
- 03转换外部数据为领域类型
- 04保留异常链
- 05处理批次中的部分失败
- 06使用 Pydantic 校验复杂输入
适用场景
- 01校验用户输入和 API 参数
- 02设计应用的异常层级
- 03处理批量操作中的失败
- 04为用户生成清晰的错误消息
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill python-error-handling安装后在 Claude Code 中输入/python-error-handling确认已加载。
附带文件references/details.md
详细介绍
Python 错误处理
通过恰当的输入验证、有意义的异常以及优雅的失败处理,构建健壮的 Python 应用。良好的错误处理能让调试更轻松,让系统更可靠。
何时使用本技能
- 验证用户输入和 API 参数
- 为应用设计异常层次结构
- 处理批处理操作中的部分失败
- 将外部数据转换为领域类型
- 构建用户友好的错误消息
- 实现快速失败(fail-fast)验证模式
核心概念
1. 快速失败
在昂贵操作之前尽早验证输入。尽可能一次性报告所有验证错误。
2. 有意义的异常
使用合适的异常类型并附加上下文。消息应说明什么失败了、为什么失败以及如何修复。
3. 部分失败
在批处理操作中,不要让单个失败中止一切。分别跟踪成功和失败。
4. 保留上下文
链式抛出异常,以保留完整的错误追踪链用于调试。
快速开始
def fetch_page(url: str, page_size: int) -> Page:
if not url:
raise ValueError("'url' is required")
if not 1 <= page_size <= 100:
raise ValueError(f"'page_size' must be 1-100, got {page_size}")
# Now safe to proceed...
基本模式
模式 1:提前进行输入验证
在任何处理开始之前,在 API 边界处验证所有输入。
def process_order(
order_id: str,
quantity: int,
discount_percent: float,
) -> OrderResult:
"""Process an order with validation."""
# Validate required fields
if not order_id:
raise ValueError("'order_id' is required")
# Validate ranges
if quantity <= 0:
raise ValueError(f"'quantity' must be positive, got {quantity}")
if not 0 <= discount_percent <= 100:
raise ValueError(
f"'discount_percent' must be 0-100, got {discount_percent}"
)
# Validation passed, proceed with processing
return _process_validated_order(order_id, quantity, discount_percent)
模式 2:尽早转换为领域类型
在系统边界处将字符串和外部数据解析为有类型的领域对象。
from enum import Enum
class OutputFormat(Enum):
JSON = "json"
CSV = "csv"
PARQUET = "parquet"
def parse_output_format(value: str) -> OutputFormat:
"""Parse string to OutputFormat enum.
Args:
value: Format string from user input.
Returns:
Validated OutputFormat enum member.
Raises:
ValueError: If format is not recognized.
"""
try:
return OutputFormat(value.lower())
except ValueError:
valid_formats = [f.value for f in OutputFormat]
raise ValueError(
f"Invalid format '{value}'. "
f"Valid options: {', '.join(valid_formats)}"
)
# Usage at API boundary
def export_data(data: list[dict], format_str: str) -> bytes:
output_format = parse_output_format(format_str) # Fail fast
# Rest of function uses typed OutputFormat
...
模式 3:使用 Pydantic 进行复杂验证
使用 Pydantic 模型进行结构化输入验证,并自动生成错误消息。
from pydantic import BaseModel, Field, field_validator
class CreateUserInput(BaseModel):
"""Input model for user creation."""
email: str = Field(..., min_length=5, max_length=255)
name: str = Field(..., min_length=1, max_length=100)
age: int = Field(ge=0, le=150)
@field_validator("email")
@classmethod
def validate_email_format(cls, v: str) -> str:
if "@" not in v or "." not in v.split("@")[-1]:
raise ValueError("Invalid email format")
return v.lower()
@field_validator("name")
@classmethod
def normalize_name(cls, v: str) -> str:
return v.strip().title()
# Usage
try:
user_input = CreateUserInput(
email="[email protected]",
name="john doe",
age=25,
)
except ValidationError as e:
# Pydantic provides detailed error information
print(e.errors())
模式 4:将错误映射到标准异常
恰当地使用 Python 内置异常类型,并按需添加上下文。
| 失败类型 | 异常 | 示例 |
|---|---|---|
| 无效输入 | ValueError | 参数值错误 |
| 类型错误 | TypeError | 期望字符串,得到 int |
| 缺少条目 | KeyError | 未找到字典键 |
| 操作失败 | RuntimeError | 服务不可用 |
| 超时 | TimeoutError | 操作耗时过长 |
| 文件未找到 | FileNotFoundError | 路径不存在 |
| 权限被拒绝 | PermissionError | 访问被禁止 |
# Good: Specific exception with context
raise ValueError(f"'page_size' must be 1-100, got {page_size}")
# Avoid: Generic exception, no context
raise Exception("Invalid parameter")
详细示例与模式
详细章节(以 ## Advanced Patterns 开头)位于 references/details.md。当上方的导航摘要不够用时,请阅读该文件。
最佳实践总结
- 尽早验证 - 在昂贵操作之前检查输入
- 使用具体的异常 - 使用
ValueError、TypeError,而非通用的Exception - 包含上下文 - 消息应说明是什么、为什么以及如何修复
- 在边界处转换类型 - 尽早将字符串解析为枚举/领域类型
- 链式抛出异常 - 使用
raise ... from e保留调试信息 - 处理部分失败 - 不要因单个条目错误而中止整个批次
- 使用 Pydantic - 用于具有结构化错误的复杂输入验证
- 记录失败模式 - Docstring 应列出可能的异常
- 带上下文记录日志 - 包含 ID、计数和其他调试信息
- 测试错误路径 - 验证异常被正确抛出
评论
支持 Markdown