Help us improve
Share bugs, ideas, or general feedback.
From golang
Go错误处理规范:禁止单行if err、必须记录日志(lazygophers/log或slog)、禁止包装错误、errors.Join聚合、sentinel errors模式。处理Go错误和异常时自动加载。
npx claudepluginhub lazygophers/ccplugin --plugin golangHow this skill is triggered — by the user, by Claude, or both
Slash command
/golang:errorsonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- **dev** - 开发专家(主要使用者)
Implements and reviews Go error handling: creates/wraps errors with fmt.Errorf, checks via errors.Is/As/Join, uses sentinels/custom types, logs with slog. Audits codebases and PRs.
Guides Go error handling: sentinels vs custom types, fmt.Errorf wrapping (%w/%v), error flow, propagation across packages, errors.Is/As, with anti-pattern checker script.
Detects and fixes Go error handling antipatterns like log-and-return double-handling, log-and-wrap helpers across codebases. Use for auditing error hygiene, finding violations, ensuring errors handled once.
Share bugs, ideas, or general feedback.
| 场景 | Skill | 说明 |
|---|---|---|
| 核心规范 | Skills(golang:core) | 核心规范:强制约定、代码格式 |
| 工具库 | Skills(golang:libs) | 优先库规范:lazygophers/log |
| 并发错误 | Skills(golang:concurrency) | errgroup 错误处理 |
log.Errorf("err:%v", err) 统一格式fmt.Errorf/errors.Wrap/errors.Wrapf 包装,直接返回原始错误log.Fatalf 而非 panicif err != nil { return err }if err := eg.Wait(); err != nil { return err }_, _ := ...fmt.Errorf("...: %w", err)data, err := os.ReadFile(path)
if err != nil {
log.Errorf("err:%v", err)
return nil, err
}
err = eg.Wait()
if err != nil {
log.Errorf("err:%v", err)
return err
}
当需要收集多个错误时使用 errors.Join:
var errs []error
for _, item := range items {
err := processItem(item)
if err != nil {
log.Errorf("err:%v", err)
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
var (
ErrNotFound = errors.New("not found")
ErrForbidden = errors.New("forbidden")
ErrBadRequest = errors.New("bad request")
)
// 直接比较
if err == ErrNotFound {
return nil, err
}
// 项目自定义错误码
if xerror.CheckCode(err, CodeNotFound) {
return nil, err
}
// 类型检查函数
if IsNotFoundErr(err) {
return nil, err
}
file, err := os.Open(path)
if err != nil {
log.Errorf("err:%v", err)
return nil, err
}
defer file.Close()
import "github.com/lazygophers/log"
log.Infof("user registered: %s", username)
log.Warnf("cache miss for key: %s", key)
log.Errorf("err:%v", err)
log.Fatalf("failed to load config: %v", err)
import "log/slog"
slog.Info("user registered", "username", name, "email", email)
slog.Warn("cache miss", "key", key)
slog.Error("operation failed", "err", err, "user_id", uid)
func init() {
config, err := loadConfig()
if err != nil {
log.Errorf("err:%v", err)
log.Fatalf("failed to load config")
}
}
| AI 可能的理性化解释 | 实际应该检查的内容 | 严重程度 |
|---|---|---|
| "单行 if err 更简洁" | 是否所有 error 多行处理? | 高 |
| "fmt.Errorf 加上下文更好" | 是否禁止包装,直接返回原始错误? | 高 |
| "errors.Is/As 更现代" | 是否使用项目规定的错误判断方式? | 中 |
| "panic 快速失败更好" | 是否使用 log.Fatalf 而非 panic? | 高 |
| "err 日志太多了" | 是否每个错误点都有日志? | 高 |
| "logrus/zap 更强大" | 是否使用 lazygophers/log 或 slog? | 中 |
log.Errorf("err:%v", err) 统一格式