

新闻资讯
技术学院Go错误处理核心陷阱是忽略、裸传、误判和静默:忽略err埋雷,裸传暴露敏感信息,类型断言被包装破坏,goroutine错误未导出。应记录/转换/传播/终止,用errors.Is/As、errgroup、脱敏返回。
Go 错误处理最常踩的坑,不是不会写 if err != nil,而是写了却没真正“处理”——错误被忽略、被吞掉、被乱包、被裸传,最终让故障在日志里隐身、在生产环境里爆发。
err 返回值:最隐蔽也最危险的“省事”用 _ 丢弃错误不是偷懒,是主动埋雷。一旦 os.Open 失败,file 是 nil,后续 file.Read 直接 panic;json.Unmarshal 解析失败却不检查,就拿脏数据往下走。
error 的函数用 _ 忽略错误if err != nil {
log.Printf("warn: config load failed, using defaults: %v", err)
return defaultConfig
}go vet -tags=errorlint 或静态检查工具(如 errcheck)自动捕获这类遗漏return db.QueryRow(...) 出错时直接返回 *pq.Error 或 sql.ErrNoRows,前端收到 "pq: password authentication failed for user 'prod_db_admin'" 这类响应,等于把数据库凭据和部署结构暴露出去。
fmt.Errorf("获取用户失败:%w", err) 包装,再用 errors.Is 判断是否为预期错误(如 errors.Is(err, sql.ErrNoRows))"用户不存在",而非原始驱动错误写 if e, ok := err.(*os.PathErr 看似精准,但只要上游用了
or); okfmt.Errorf("read failed: %w", err) 或 errors.Wrap,断言立刻失败——因为包装后的错误是 *fmt.wrapError,不是 *os.PathError。
立即学习“go语言免费学习笔记(深入)”;
os.IsNotExist(err)、os.IsPermission(err)、net.IsTimeout(err)
errors.As 替代直接断言:var pathErr *os.PathError
if errors.As(err, &pathErr) {
log.Printf("路径错误:%s", pathErr.Path)
}errors.Unwrap(),确保包装链可追溯启动一个 go doSomething(),里面出错只打印日志不通知主流程,结果任务失败了没人知道,定时任务漏跑、消息没发、状态没更新,全靠监控告警“被动发现”。
chan error 或 errgroup.Group
context.Context + errgroup:g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
return processItem(ctx, item)
})
if err := g.Wait(); err != nil {
return fmt.Errorf("batch failed: %w", err)
}log.Fatal 或 panic ——它杀不掉其他 goroutine,也逃不出主流程控制错误不是异常的替代品,它是 Go 里最普通的值;而“处理错误”的本质,是决定这个值该被记录、转换、传播,还是终止流程——所有反模式,都源于跳过了这个决策过程。