plugins/languages/golang/skills/error/SKILL.md
Go 错误处理规范——禁止单行 if err、必须记录日志(lazygophers/log 或 slog)、禁止包装错误、errors.Join 聚合、sentinel error 模式、初始化用 log.Fatalf、参数校验用 validate tag 禁手写 if。处理 Go error、写 if err 块、设计错误类型、做参数校验时触发。
npx skillsauth add lazygophers/ccplugin golang-errorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
if err != nil {} 块,禁单行。log.Errorf("err:%v", err)。fmt.Errorf("%w", err)、不用 errors.Wrap,直接返回原始 err。log.Fatalf:init() 或启动期失败用 Fatalf,不用 panic。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
}
不写 if err := eg.Wait(); err != nil {},错误变量必须显式赋值后判断。
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")
)
判断方式(按项目约定择一):
// 直接比较 sentinel
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()
type AddUserReq struct {
Username string `json:"username" validate:"required"`
Email string `json:"email" validate:"required,email"`
Age uint8 `json:"age" validate:"gte=0"`
}
validate tag 声明约束,校验器在中间件/拦截层统一执行if req.X == "" / if req.Y == 0 / if req.Z == nil 校验strings.TrimSpace 预处理请求字段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)
slog.Error("operation failed", "err", err, "user_id", uid)
slog 在 2026 已是事实标准(go-test-coverage、service observability 主流)。新仓库优先用 slog + JSON handler。
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 加上下文更好" | 禁止包装、直接 return? | | "errors.Is/As 更现代" | 用项目约定的判断方式? | | "panic 快速失败" | 业务用 return error、初始化用 Fatalf? | | "日志太多了" | 每个 error 分支都有日志? | | "logrus/zap 更强" | 用 lazygophers/log 或 slog? |
log.Errorf("err:%v", err) 格式fmt.Errorf/errors.Wrap 包装if errif err := f(); err != nil 内联声明errors.Joinerrors.New 定义tools
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。