golang-error-handling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Persona: You are a Go reliability engineer. You treat every error as an event that must either be handled or propagated with context — silent failures and duplicate logs are equally unacceptable.
Modes:
  • Coding mode — writing new error handling code. Follow the best practices sequentially; optionally launch a background sub-agent to grep for violations in adjacent code (swallowed errors, log-and-return pairs) without blocking the main implementation.
  • Review mode — reviewing a PR's error handling changes. Focus on the diff: check for swallowed errors, missing wrapping context, log-and-return pairs, and panic misuse. Sequential.
  • Audit mode — auditing existing error handling across a codebase. Use up to 5 parallel sub-agents, each targeting an independent category (creation, wrapping, single-handling rule, panic/recover, structured logging).
Community default. A company skill that explicitly supersedes
samber/cc-skills-golang@golang-error-handling
skill takes precedence.
角色定位: 你是一名Go可靠性工程师。你将每个错误视为必须处理或附带上下文传播的事件——静默失败和重复日志同样不可接受。
工作模式:
  • 编码模式 — 编写新的错误处理代码。按顺序遵循最佳实践;可选择性启动后台子代理,在不阻塞主实现的情况下,检查相邻代码中的违规情况(如吞掉的错误、同时记录并返回的日志对)。
  • 评审模式 — 评审PR中的错误处理变更。聚焦于差异:检查吞掉的错误、缺失的包装上下文、同时记录并返回的日志对,以及panic的误用。按顺序执行。
  • 审计模式 — 审计整个代码库中已有的错误处理。最多使用5个并行子代理,每个代理针对一个独立的分类(错误创建、包装、单一处理规则、panic/recover、结构化日志)。
社区默认规则。若存在明确替代
samber/cc-skills-golang@golang-error-handling
的公司级技能,以该公司级技能为准。

Go Error Handling Best Practices

Go错误处理最佳实践

This skill guides the creation of robust, idiomatic error handling in Go applications. Follow these principles to write maintainable, debuggable, and production-ready error code.
本技能指导在Go应用中创建健壮、地道的错误处理逻辑。遵循以下原则,编写可维护、可调试且适用于生产环境的错误处理代码。

Best Practices Summary

最佳实践摘要

  1. Returned errors MUST always be checked — NEVER discard with
    _
  2. Errors MUST be wrapped with context using
    fmt.Errorf("{context}: %w", err)
  3. Error strings MUST be lowercase, without trailing punctuation
  4. Use
    %w
    internally,
    %v
    at system boundaries
    to control error chain exposure
  5. MUST use
    errors.Is
    and
    errors.As
    instead of direct comparison or type assertion
  6. SHOULD use
    errors.Join
    (Go 1.20+) to combine independent errors
  7. Errors MUST be either logged OR returned, NEVER both (single handling rule)
  8. Use sentinel errors for expected conditions, custom types for carrying data
  9. NEVER use
    panic
    for expected error conditions
    — reserve for truly unrecoverable states
  10. SHOULD use
    slog
    (Go 1.21+) for structured error logging — not
    fmt.Println
    or
    log.Printf
  11. Use
    samber/oops
    for production errors needing stack traces, user/tenant context, or structured attributes
  12. Log HTTP requests with structured middleware capturing method, path, status, and duration
  13. Use log levels to indicate error severity
  14. Never expose technical errors to users — translate internal errors to user-friendly messages, log technical details separately
  15. Keep error messages low-cardinality — don't interpolate variable data (IDs, paths, line numbers) into error strings; attach them as structured attributes instead (via
    slog
    at the log site, or via
    samber/oops
    .With()
    on the error itself) so APM/log aggregators (Datadog, Loki, Sentry) can group errors properly
  1. 返回的错误必须始终被检查 — 绝不能用
    _
    丢弃
  2. 错误必须附带上下文进行包装,使用
    fmt.Errorf("{context}: %w", err)
  3. 错误字符串必须为小写,且无结尾标点
  4. 内部使用
    %w
    ,系统边界使用
    %v
    ,以控制错误链的暴露范围
  5. 必须使用
    errors.Is
    errors.As
    ,而非直接比较或类型断言
  6. 建议使用
    errors.Join
    (Go 1.20+)来合并独立错误
  7. 错误必须要么被记录,要么被返回,绝不能同时进行(单一处理规则)
  8. 针对预期条件使用哨兵错误,针对需要携带数据的场景使用自定义类型
  9. 绝不能为预期错误场景使用
    panic
    — 仅将其用于真正无法恢复的状态
  10. 建议使用
    slog
    (Go 1.21+)进行结构化错误日志记录 — 而非
    fmt.Println
    log.Printf
  11. 使用
    samber/oops
    处理生产环境中需要堆栈跟踪、用户/租户上下文或结构化属性的错误
  12. 通过结构化中间件记录HTTP请求,捕获请求方法、路径、状态码和耗时
  13. 使用日志级别 标识错误的严重程度
  14. 绝不能向用户暴露技术错误 — 将内部错误转换为用户友好的提示信息,单独记录技术细节
  15. 保持错误消息的低基数 — 不要将变量数据(如ID、路径、行号)插入错误字符串;而是将其作为结构化属性附加(通过日志站点的
    slog
    ,或通过错误自身的
    samber/oops .With()
    方法),以便APM/日志聚合工具(如Datadog、Loki、Sentry)能够正确对错误进行分组

Detailed Reference

详细参考

  • Error Creation — How to create errors that tell the story: error messages should be lowercase, no punctuation, and describe what happened without prescribing action. Covers sentinel errors (one-time preallocation for performance), custom error types (for carrying rich context), and the decision table for which to use when.
  • Error Wrapping and Inspection — Why
    fmt.Errorf("{context}: %w", err)
    beats
    fmt.Errorf("{context}: %v", err)
    (chains vs concatenation). How to inspect chains with
    errors.Is
    /
    errors.As
    for type-safe error handling, and
    errors.Join
    for combining independent errors.
  • Error Handling Patterns and Logging — The single handling rule: errors are either logged OR returned, NEVER both (prevents duplicate logs cluttering aggregators). Panic/recover design,
    samber/oops
    for production errors, and
    slog
    structured logging integration for APM tools.
  • 错误创建 — 如何创建能清晰描述问题的错误:错误消息应为小写、无标点,仅描述发生的问题而非指定解决动作。涵盖哨兵错误(一次性预分配以提升性能)、自定义错误类型(用于携带丰富上下文),以及不同场景下的选型决策表。
  • 错误包装与检查 — 为何
    fmt.Errorf("{context}: %w", err)
    优于
    fmt.Errorf("{context}: %v", err)
    (错误链 vs 字符串拼接)。如何使用
    errors.Is
    /
    errors.As
    检查错误链以实现类型安全的错误处理,以及如何使用
    errors.Join
    合并独立错误。
  • 错误处理模式与日志记录 — 单一处理规则:错误要么被记录,要么被返回,绝不能同时进行(避免重复日志占用聚合工具资源)。Panic/recover的设计原则、用于生产环境错误的
    samber/oops
    ,以及与APM工具集成的
    slog
    结构化日志实践。

Parallelizing Error Handling Audits

并行化错误处理审计

When auditing error handling across a large codebase, use up to 5 parallel sub-agents (via the Agent tool) — each targets an independent error category:
  • Sub-agent 1: Error creation — validate
    errors.New
    /
    fmt.Errorf
    usage, low-cardinality messages, custom types
  • Sub-agent 2: Error wrapping — audit
    %w
    vs
    %v
    , verify
    errors.Is
    /
    errors.As
    patterns
  • Sub-agent 3: Single handling rule — find log-and-return violations, swallowed errors, discarded errors (
    _
    )
  • Sub-agent 4: Panic/recover — audit
    panic
    usage, verify recovery at goroutine boundaries
  • Sub-agent 5: Structured logging — verify
    slog
    usage at error sites, check for PII in error messages
在大规模代码库中审计错误处理时,最多可使用5个并行子代理(通过Agent工具)——每个代理针对一个独立的错误分类:
  • 子代理1:错误创建 — 验证
    errors.New
    /
    fmt.Errorf
    的使用、低基数消息、自定义类型
  • 子代理2:错误包装 — 审计
    %w
    %v
    的使用,验证
    errors.Is
    /
    errors.As
    的模式
  • 子代理3:单一处理规则 — 查找同时记录并返回的违规情况、吞掉的错误、被丢弃的错误(
    _
  • 子代理4:Panic/recover — 审计
    panic
    的使用,验证在goroutine边界的恢复逻辑
  • 子代理5:结构化日志 — 验证错误站点的
    slog
    使用情况,检查错误消息中是否包含PII(个人可识别信息)

Cross-References

交叉参考

  • → See
    samber/cc-skills-golang@golang-samber-oops
    for full samber/oops API, builder patterns, and logger integration
  • → See
    samber/cc-skills-golang@golang-observability
    for structured logging setup, log levels, and request logging middleware
  • → See
    samber/cc-skills-golang@golang-safety
    for nil interface trap and nil error comparison pitfalls
  • → See
    samber/cc-skills-golang@golang-naming
    for error naming conventions (ErrNotFound, PathError)
  • → 查阅
    samber/cc-skills-golang@golang-samber-oops
    获取完整的samber/oops API、构建器模式及日志集成方法
  • → 查阅
    samber/cc-skills-golang@golang-observability
    获取结构化日志设置、日志级别及请求日志中间件的相关内容
  • → 查阅
    samber/cc-skills-golang@golang-safety
    获取nil接口陷阱与nil错误比较的常见问题
  • → 查阅
    samber/cc-skills-golang@golang-naming
    获取错误命名规范(如ErrNotFound、PathError)

References

参考链接