dotnet-exception-handling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

.NET Exception Handling Quality Improvement

.NET异常处理质量改进

Purpose

目的

Systematic investigation and remediation of .NET exception handling anti-patterns. Detects, documents, and fixes the 10 most common exception handling mistakes in .NET applications.
Use when: Preparing for production, code quality audits, security reviews, or onboarding to a .NET codebase.
系统性排查并修复.NET异常处理反模式。检测、记录并修复.NET应用中最常见的10种异常处理错误。
适用场景:生产环境准备、代码质量审计、安全审查,或是接手.NET代码库时。

Usage

使用方法

bash
undefined
bash
undefined

Investigation only (default)

仅排查(默认)

/dotnet-exception-handling <path-to-dotnet-project>
/dotnet-exception-handling <path-to-dotnet-project>

Filter by severity

按严重程度过滤

/dotnet-exception-handling <project-path> --priority critical
/dotnet-exception-handling <project-path> --priority critical

Auto-implement all fixes

自动实施所有修复

/dotnet-exception-handling <project-path> --fix-all

**Arguments**:

- `project-path`: Directory containing .csproj or .sln (default: current directory)
- `--priority`: `critical` | `high` | `medium` | `low` | `all` (default: `all`)
- `--fix-all`: Implement fixes automatically (default: investigate only)
/dotnet-exception-handling <project-path> --fix-all

**参数**:

- `project-path`:包含.csproj或.sln的目录(默认:当前目录)
- `--priority`:`critical` | `high` | `medium` | `low` | `all`(默认:`all`)
- `--fix-all`:自动实施修复(默认:仅排查)

The 10 Common Mistakes

10种常见错误

  1. Catching Exception Too Broadly - Base
    Exception
    instead of specific types
  2. Swallowing Exceptions Silently - Empty catch blocks hiding errors
  3. Using
    throw ex;
    - Resets stack traces (use
    throw;
    )
  4. Wrapping Everything in Try/Catch - Defensive coding clutter
  5. Exceptions for Control Flow - Performance overhead for expected conditions
  6. Forgetting to Await Async - Unhandled exceptions on background threads
  7. Ignoring Background Task Exceptions - Fire-and-forget losing errors
  8. Generic Exception Types - Vague
    new Exception()
    instead of specific types
  9. Losing Inner Exceptions - Breaking exception chains
  10. Missing Global Handler - No centralized error handling (stack traces exposed)
Detailed descriptions, detection patterns, and fix templates → see
reference.md
  1. 过度宽泛捕获Exception - 捕获基类
    Exception
    而非特定类型
  2. 静默吞噬异常 - 空catch块隐藏错误
  3. 使用
    throw ex;
    - 重置堆栈跟踪(应使用
    throw;
  4. 所有代码都包裹Try/Catch - 防御性编码造成代码冗余
  5. 用异常实现控制流 - 针对预期场景使用异常会带来性能开销
  6. 异步操作忘记Await - 后台线程出现未处理异常
  7. 忽略后台任务异常 - 即发即弃的任务丢失错误信息
  8. 泛型异常类型 - 使用模糊的
    new Exception()
    而非特定类型
  9. 丢失内部异常 - 中断异常链
  10. 缺少全局处理器 - 无集中式错误处理(堆栈跟踪暴露)
详细说明、检测模式和修复模板 → 查看
reference.md

Execution Workflow

执行工作流

Phase 1: Investigation (6 Steps)

阶段1:排查(6步)

Step 1: Project Detection
  • Scan for .csproj, .sln files
  • Identify project types (ASP.NET Core, worker services, libraries)
  • Count C# files for scope estimation
Step 2: Parallel Analysis
  • Deploy 5 specialized agents:
    • Background Worker Specialist
    • API Layer Specialist
    • Service Layer Specialist
    • Data Layer Specialist
    • Infrastructure Specialist
Step 3: Violation Detection
  • Use
    rg -P
    (ripgrep PCRE mode) for pattern matching:
    bash
    # Mistake #1: Broad catches
    rg -P 'catch\s*\(Exception\b' --glob '*.cs'
    
    # Mistake #2: Empty catches
    rg -P 'catch[^{]*\{\s*(//[^\n]*)?\s*\}' --glob '*.cs'
    
    # Mistake #3: throw ex
    rg 'throw\s+ex;' --glob '*.cs'
  • See
    reference.md
    for complete pattern list
Step 4: Severity Classification
  • CRITICAL: Security (stack trace exposure, missing global handler)
  • HIGH: Reliability (swallowed exceptions, broad catches)
  • MEDIUM: Code quality (excessive try/catch)
  • LOW: Style issues
Step 5: Findings Report
  • Generate markdown with file:line references
  • Code snippets + recommended fixes
  • Priority-based roadmap
Step 6: Knowledge Capture
  • Store in
    .claude/runtime/logs/EXCEPTION_INVESTIGATION_YYYY-MM-DD.md
  • Update project memory
步骤1:项目检测
  • 扫描.csproj、.sln文件
  • 识别项目类型(ASP.NET Core、工作服务、类库)
  • 统计C#文件数量以评估范围
步骤2:并行分析
  • 部署5个专业Agent:
    • 后台工作服务专家
    • API层专家
    • 服务层专家
    • 数据层专家
    • 基础设施专家
步骤3:违规检测
  • 使用
    rg -P
    (ripgrep的PCRE模式)进行模式匹配:
    bash
    # 错误1:宽泛捕获
    rg -P 'catch\s*\(Exception\b' --glob '*.cs'
    
    # 错误2:空catch块
    rg -P 'catch[^{]*\{\s*(//[^\n]*)?\s*\}' --glob '*.cs'
    
    # 错误3:throw ex
    rg 'throw\s+ex;' --glob '*.cs'
  • 完整模式列表请查看
    reference.md
步骤4:严重程度分类
  • CRITICAL(严重):安全问题(堆栈跟踪暴露、缺少全局处理器)
  • HIGH(高):可靠性问题(异常被吞噬、宽泛捕获)
  • MEDIUM(中):代码质量问题(过多Try/Catch)
  • LOW(低):风格问题
步骤5:排查结果报告
  • 生成包含文件:行号引用的Markdown报告
  • 代码片段 + 推荐修复方案
  • 基于优先级的修复路线图
步骤6:知识留存
  • 存储至
    .claude/runtime/logs/EXCEPTION_INVESTIGATION_YYYY-MM-DD.md
  • 更新项目记忆

Phase 2: Development (If --fix-all)

阶段2:开发(若使用--fix-all)

Step 7: Orchestrate Default Workflow
  • Create GitHub issue with findings
  • Set up worktree for fixes
  • Implement GlobalExceptionHandler, Result<T>, etc.
  • Write comprehensive tests (TDD)
  • Three-agent review (reviewer, security, philosophy)
Step 8: Validation
  • All tests pass
  • Security: Zero stack traces
  • Performance: <5ms p99 overhead
步骤7:统筹默认工作流
  • 创建包含排查结果的GitHub Issue
  • 为修复工作设置工作区
  • 实现GlobalExceptionHandler、Result<T>
  • 编写全面测试(测试驱动开发TDD)
  • 三位Agent评审(评审专家、安全专家、架构专家)
步骤8:验证
  • 所有测试通过
  • 安全:无堆栈跟踪暴露
  • 性能:p99开销<5ms

Quick Start Examples

快速开始示例

Example 1: Investigation Only

示例1:仅排查

bash
/dotnet-exception-handling ./src/MyApi
Output: Investigation report with 23 violations (1 CRITICAL, 8 HIGH, 12 MEDIUM, 2 LOW)
bash
/dotnet-exception-handling ./src/MyApi
输出:排查报告,包含23个违规项(1个CRITICAL、8个HIGH、12个MEDIUM、2个LOW)

Example 2: Fix Critical Only

示例2:仅修复严重问题

bash
/dotnet-exception-handling ./src/MyApi --priority critical --fix-all
Output: GitHub issue + PR implementing GlobalExceptionHandler + 15 tests
bash
/dotnet-exception-handling ./src/MyApi --priority critical --fix-all
输出:GitHub Issue + 实现GlobalExceptionHandler的PR + 15个测试

Example 3: Complete Fix

示例3:完整修复

bash
/dotnet-exception-handling ./src/MyApi --fix-all
Output: 23 violations fixed, 67 tests, PR ready (CI passing)
bash
/dotnet-exception-handling ./src/MyApi --fix-all
输出:23个违规项已修复,67个测试,PR就绪(CI已通过)

Core Architecture Patterns

核心架构模式

GlobalExceptionHandler (IExceptionHandler)

GlobalExceptionHandler(IExceptionHandler)

Centralized exception-to-HTTP mapping for ASP.NET Core:
csharp
public class GlobalExceptionHandler : IExceptionHandler
{
    public async ValueTask<bool> TryHandleAsync(
        HttpContext httpContext,
        Exception exception,
        CancellationToken cancellationToken)
    {
        var (statusCode, title) = exception switch
        {
            ArgumentException => (400, "Invalid request"),
            NotFoundException => (404, "Not found"),
            ConflictException => (409, "Conflict"),
            _ => (500, "Internal server error")
        };

        httpContext.Response.StatusCode = statusCode;
        await httpContext.Response.WriteAsJsonAsync(new ProblemDetails
        {
            Status = statusCode,
            Title = title,
            Detail = statusCode >= 500
                ? "An error occurred"
                : exception.Message
        }, cancellationToken);

        return true;
    }
}

// Registration in Program.cs
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
app.UseExceptionHandler();
Benefits: Zero stack traces, consistent responses, no try/catch in controllers
ASP.NET Core的集中式异常到HTTP响应映射:
csharp
public class GlobalExceptionHandler : IExceptionHandler
{
    public async ValueTask<bool> TryHandleAsync(
        HttpContext httpContext,
        Exception exception,
        CancellationToken cancellationToken)
    {
        var (statusCode, title) = exception switch
        {
            ArgumentException => (400, "Invalid request"),
            NotFoundException => (404, "Not found"),
            ConflictException => (409, "Conflict"),
            _ => (500, "Internal server error")
        };

        httpContext.Response.StatusCode = statusCode;
        await httpContext.Response.WriteAsJsonAsync(new ProblemDetails
        {
            Status = statusCode,
            Title = title,
            Detail = statusCode >= 500
                ? "An error occurred"
                : exception.Message
        }, cancellationToken);

        return true;
    }
}

// 在Program.cs中注册
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
app.UseExceptionHandler();
优势:无堆栈跟踪暴露、响应一致、控制器中无需Try/Catch

Result<T> Pattern

Result<T>模式

Railway-oriented programming for validation (no exceptions for expected conditions):
csharp
public Result<Order> ValidateOrder(CreateOrderDto dto)
{
    if (dto.Items.Count == 0)
        return Result<Order>.Failure("Order must have items");

    return Result<Order>.Success(new Order(dto));
}

// Controller usage
var result = await _service.ValidateOrder(dto);
return result.Match(
    onSuccess: order => Ok(order),
    onFailure: error => BadRequest(error)
);
Benefits: 100x faster than exceptions, explicit error handling, better composition
Complete implementations → see
examples.md
面向铁路编程的验证模式(预期场景不使用异常):
csharp
public Result<Order> ValidateOrder(CreateOrderDto dto)
{
    if (dto.Items.Count == 0)
        return Result<Order>.Failure("Order must have items");

    return Result<Order>.Success(new Order(dto));
}

// 控制器使用示例
var result = await _service.ValidateOrder(dto);
return result.Match(
    onSuccess: order => Ok(order),
    onFailure: error => BadRequest(error)
);
优势:比异常快100倍、显式错误处理、组合性更好
完整实现 → 查看
examples.md

Navigation Guide

导航指南

When to Read Supporting Files

何时阅读支持文件

reference.md - Read when you need:
  • Detailed descriptions of all 10 exception handling mistakes
  • Complete detection patterns for ripgrep/grep
  • Fix templates for each mistake type
  • Security considerations (OWASP compliance, stack trace prevention)
  • Severity classification reference
  • Integration patterns (Azure SDK, EF Core, Service Bus)
examples.md - Read when you need:
  • Before/after code examples for each mistake
  • Complete working implementations (GlobalExceptionHandler, Result<T>, DbContextExtensions)
  • Real-world scenarios (order processing, payment systems)
  • Unit and integration testing patterns
  • Copy-paste ready code
patterns.md - Read when you need:
  • Architecture decision trees (global handler vs try/catch, Result<T> vs exceptions)
  • Background worker exception handling patterns
  • Azure SDK exception translation patterns
  • EF Core concurrency and transaction patterns
  • Performance benchmarks (Result<T> vs exceptions)
  • Anti-patterns to avoid
reference.md - 当你需要以下内容时阅读:
  • 所有10种异常处理错误的详细说明
  • ripgrep/grep的完整检测模式
  • 每种错误类型的修复模板
  • 安全注意事项(OWASP合规、堆栈跟踪防护)
  • 严重程度分类参考
  • 集成模式(Azure SDK、EF Core、Service Bus)
examples.md - 当你需要以下内容时阅读:
  • 每种错误的前后代码示例
  • 完整可运行实现(GlobalExceptionHandler、Result<T>、DbContextExtensions)
  • 真实场景示例(订单处理、支付系统)
  • 单元测试和集成测试模式
  • 可直接复制粘贴的代码
patterns.md - 当你需要以下内容时阅读:
  • 架构决策树(全局处理器vs Try/Catch、Result<T> vs 异常)
  • 后台工作服务异常处理模式
  • Azure SDK异常转换模式
  • EF Core并发和事务模式
  • 性能基准测试(Result<T> vs 异常)
  • 需避免的反模式

Workflow Integration

工作流集成

This skill orchestrates two canonical workflows:
  1. Investigation Workflow (Phase 1): Scope → Explore → Analyze → Classify → Report → Capture
  2. Default Workflow (Phase 2, if --fix-all): Requirements → Architecture → TDD → Implementation → Review → CI/CD
本技能统筹两个标准工作流:
  1. 排查工作流(阶段1):范围确定 → 探索 → 分析 → 分类 → 报告 → 留存
  2. 默认工作流(阶段2,若使用--fix-all):需求 → 架构 → TDD → 实现 → 评审 → CI/CD

References

参考资料

Version History

版本历史

  • v1.0.0 (2026-02-10): Initial implementation based on CyberGym investigation (52 violations fixed, 87 tests)
  • v1.0.0(2026-02-10):基于CyberGym排查的初始实现(修复52个违规项,87个测试)

Known Limitations

已知限制

  • Requires .NET 6+ for IExceptionHandler
  • Result<T> pattern targets C# 7.0+ (struct readonly, expression-bodied members)
  • Patterns specific to ASP.NET Core (may not apply to class libraries)
  • 需要.NET 6+以支持IExceptionHandler
  • Result<T>模式针对C# 7.0+(只读结构体、表达式主体成员)
  • 模式特定于ASP.NET Core(可能不适用于类库)