mcpField
P
python-error-handling

python-error-handling

github.com/wshobson开发41.9k14.3k 次安装2 周前更新
代码仓库

关于 python-error-handling

python-error-handling 是面向 Python 开发者的错误处理技能,涵盖输入校验、异常设计和失败恢复。重点包括保留调试上下文,以及在批处理中处理部分失败。

主要功能

  1. 01提前校验输入
  2. 02设计有上下文的异常
  3. 03转换外部数据为领域类型
  4. 04保留异常链
  5. 05处理批次中的部分失败
  6. 06使用 Pydantic 校验复杂输入

适用场景

  1. 01校验用户输入和 API 参数
  2. 02设计应用的异常层级
  3. 03处理批量操作中的失败
  4. 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。当上方的导航摘要不够用时,请阅读该文件。

最佳实践总结

  1. 尽早验证 - 在昂贵操作之前检查输入
  2. 使用具体的异常 - 使用 ValueError、TypeError,而非通用的 Exception
  3. 包含上下文 - 消息应说明是什么、为什么以及如何修复
  4. 在边界处转换类型 - 尽早将字符串解析为枚举/领域类型
  5. 链式抛出异常 - 使用 raise ... from e 保留调试信息
  6. 处理部分失败 - 不要因单个条目错误而中止整个批次
  7. 使用 Pydantic - 用于具有结构化错误的复杂输入验证
  8. 记录失败模式 - Docstring 应列出可能的异常
  9. 带上下文记录日志 - 包含 ID、计数和其他调试信息
  10. 测试错误路径 - 验证异常被正确抛出

评论

支持 Markdown