golang-error-handling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePersona: 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 supersedesskill takes precedence.samber/cc-skills-golang@golang-error-handling
角色定位: 你是一名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
最佳实践摘要
- Returned errors MUST always be checked — NEVER discard with
_ - Errors MUST be wrapped with context using
fmt.Errorf("{context}: %w", err) - Error strings MUST be lowercase, without trailing punctuation
- Use internally,
%wat system boundaries to control error chain exposure%v - MUST use and
errors.Isinstead of direct comparison or type assertionerrors.As - SHOULD use (Go 1.20+) to combine independent errors
errors.Join - Errors MUST be either logged OR returned, NEVER both (single handling rule)
- Use sentinel errors for expected conditions, custom types for carrying data
- NEVER use for expected error conditions — reserve for truly unrecoverable states
panic - SHOULD use (Go 1.21+) for structured error logging — not
slogorfmt.Printlnlog.Printf - Use for production errors needing stack traces, user/tenant context, or structured attributes
samber/oops - Log HTTP requests with structured middleware capturing method, path, status, and duration
- Use log levels to indicate error severity
- Never expose technical errors to users — translate internal errors to user-friendly messages, log technical details separately
- Keep error messages low-cardinality — don't interpolate variable data (IDs, paths, line numbers) into error strings; attach them as structured attributes instead (via at the log site, or via
slogsamber/oopson the error itself) so APM/log aggregators (Datadog, Loki, Sentry) can group errors properly.With()
- 返回的错误必须始终被检查 — 绝不能用丢弃
_ - 错误必须附带上下文进行包装,使用
fmt.Errorf("{context}: %w", err) - 错误字符串必须为小写,且无结尾标点
- 内部使用,系统边界使用
%w,以控制错误链的暴露范围%v - 必须使用和
errors.Is,而非直接比较或类型断言errors.As - 建议使用(Go 1.20+)来合并独立错误
errors.Join - 错误必须要么被记录,要么被返回,绝不能同时进行(单一处理规则)
- 针对预期条件使用哨兵错误,针对需要携带数据的场景使用自定义类型
- 绝不能为预期错误场景使用— 仅将其用于真正无法恢复的状态
panic - 建议使用(Go 1.21+)进行结构化错误日志记录 — 而非
slog或fmt.Printlnlog.Printf - 使用处理生产环境中需要堆栈跟踪、用户/租户上下文或结构化属性的错误
samber/oops - 通过结构化中间件记录HTTP请求,捕获请求方法、路径、状态码和耗时
- 使用日志级别 标识错误的严重程度
- 绝不能向用户暴露技术错误 — 将内部错误转换为用户友好的提示信息,单独记录技术细节
- 保持错误消息的低基数 — 不要将变量数据(如ID、路径、行号)插入错误字符串;而是将其作为结构化属性附加(通过日志站点的,或通过错误自身的
slog方法),以便APM/日志聚合工具(如Datadog、Loki、Sentry)能够正确对错误进行分组samber/oops .With()
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 — Whybeats
fmt.Errorf("{context}: %w", err)(chains vs concatenation). How to inspect chains withfmt.Errorf("{context}: %v", err)/errors.Isfor type-safe error handling, anderrors.Asfor combining independent errors.errors.Join -
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,for production errors, and
samber/oopsstructured logging integration for APM tools.slog
-
错误创建 — 如何创建能清晰描述问题的错误:错误消息应为小写、无标点,仅描述发生的问题而非指定解决动作。涵盖哨兵错误(一次性预分配以提升性能)、自定义错误类型(用于携带丰富上下文),以及不同场景下的选型决策表。
-
错误包装与检查 — 为何优于
fmt.Errorf("{context}: %w", err)(错误链 vs 字符串拼接)。如何使用fmt.Errorf("{context}: %v", err)/errors.Is检查错误链以实现类型安全的错误处理,以及如何使用errors.As合并独立错误。errors.Join -
错误处理模式与日志记录 — 单一处理规则:错误要么被记录,要么被返回,绝不能同时进行(避免重复日志占用聚合工具资源)。Panic/recover的设计原则、用于生产环境错误的,以及与APM工具集成的
samber/oops结构化日志实践。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.Newusage, low-cardinality messages, custom typesfmt.Errorf - Sub-agent 2: Error wrapping — audit vs
%w, verify%v/errors.Ispatternserrors.As - Sub-agent 3: Single handling rule — find log-and-return violations, swallowed errors, discarded errors ()
_ - Sub-agent 4: Panic/recover — audit usage, verify recovery at goroutine boundaries
panic - Sub-agent 5: Structured logging — verify usage at error sites, check for PII in error messages
slog
在大规模代码库中审计错误处理时,最多可使用5个并行子代理(通过Agent工具)——每个代理针对一个独立的错误分类:
- 子代理1:错误创建 — 验证/
errors.New的使用、低基数消息、自定义类型fmt.Errorf - 子代理2:错误包装 — 审计与
%w的使用,验证%v/errors.Is的模式errors.As - 子代理3:单一处理规则 — 查找同时记录并返回的违规情况、吞掉的错误、被丢弃的错误()
_ - 子代理4:Panic/recover — 审计的使用,验证在goroutine边界的恢复逻辑
panic - 子代理5:结构化日志 — 验证错误站点的使用情况,检查错误消息中是否包含PII(个人可识别信息)
slog
Cross-References
交叉参考
- → See for full samber/oops API, builder patterns, and logger integration
samber/cc-skills-golang@golang-samber-oops - → See for structured logging setup, log levels, and request logging middleware
samber/cc-skills-golang@golang-observability - → See for nil interface trap and nil error comparison pitfalls
samber/cc-skills-golang@golang-safety - → See for error naming conventions (ErrNotFound, PathError)
samber/cc-skills-golang@golang-naming
- → 查阅获取完整的samber/oops API、构建器模式及日志集成方法
samber/cc-skills-golang@golang-samber-oops - → 查阅获取结构化日志设置、日志级别及请求日志中间件的相关内容
samber/cc-skills-golang@golang-observability - → 查阅获取nil接口陷阱与nil错误比较的常见问题
samber/cc-skills-golang@golang-safety - → 查阅获取错误命名规范(如ErrNotFound、PathError)
samber/cc-skills-golang@golang-naming