Go错误处理最佳实践进阶从error到panic的完整指南
Go错误处理最佳实践从error到panic-recover的完整指南
文章导语
错误处理是Go的"招牌特性"——没有try-catch,只有if err != nil。但很多人只会机械地返回error,不理解错误包装、错误链、哨兵错误等进阶模式。
一、错误包装(Wrapping)
// Go 1.13+错误包装funcGetUser(idint)(*User,error){user,err:=db.FindUser(id)iferr!=nil{returnnil,fmt.Errorf("获取用户失败 id=%d: %w",id,err)}returnuser,nil}// 错误链检查iferrors.Is(err,sql.ErrNoRows){// 用户不存在}vartargetErr*ValidationErroriferrors.As(err,&targetErr){// 提取具体错误类型}二、错误处理模式
// 哨兵错误varErrNotFound=errors.New("not found")// 自定义错误类型typeValidationErrorstruct{FieldstringMsgstring}func(e*ValidationError)Error()string{returnfmt.Sprintf("%s: %s",e.Field,e.Msg)}// defer错误处理funcCopyFile(dst,srcstring)(errerror){r,err:=os.Open(src)iferr!=nil{return}deferr.Close()w,err:=os.Create(dst)iferr!=nil{return}deferfunc(){w.Close()iferr!=nil{os.Remove(dst)}}()_,err=io.Copy(w,r)return}三、全文总结
%w包装错误链,errors.Is/As检查错误链,哨兵错误定义公开错误常量,自定义错误类型携带上下文字段。
参考文献
- Go Blog - Working with Errors in Go 1.13
- Go errors包文档
- Dave Cheney - Don’t just check errors