go 错误处理设计思考
前段时间准备对线上一个golang系统服务进行内部开源,对代码里面的错误处理进行了一波优化。
优化的几个原因:
- 错误处理信息随意,未分类未定义。看到错误日志不能第一时间定位
- 错误的日志重复,有时候一个错误经过了好几层,每一层都会记录,导致日志混乱
- 错误处理不统一,使用不统一,管理也不统一
优化的解决办法:
- 对错误进行分类,统一定义和使用
- 每一个错误都有冒泡到包的顶层,处理与记日志。使用方只需定义好自己的信息
实施过程
错误分类:函数级,包模块级,系统api级。
函数级别:
还是采用 err != nil 的形式,并且做一个如下的包装。
模块级别
统一返回到对应的goroutine顶层处理
服务对外级别
适当的code和健名的message
底层错误级别
考虑及时panic,暴露有用信息
以下为代码设计:
点击查看代码
package ferrors
import (
"fmt"
"golang.org/x/xerrors"
)
//Errors 新的错误处理方式
type Errors struct {
Code int64
Msg string
}
// Error 输出错误信息
func (e Errors) Error() string {
return fmt.Sprintf("code: %d msg: %s at: %s", e.Code, e.Msg, "错误位置,堆栈信息,可选")
}
// New 创建自定义错误
func New(code int64, str string, arg ...interface{}) *Errors {
if len(arg) > 0 {
str = fmt.Sprintf(str, arg...)
}
return &Errors{Code: code, Msg: str}
}
// newErr 创建通用错误
func newErr(code int64, err error) *Errors {
switch err := err.(type) {
case *Errors:
return err
case nil:
return &Errors{Code: code, Msg: ""}
default:
return &Errors{Code: code, Msg: err.Error()}
}
}
func NewErrNotFound(err error) error {
return newErr(CodeMkNotFound, err)
}
// ErrorEcho example:使用 error wrapping
func ErrorEcho(err error) string {
return fmt.Sprintf("the error %w", err)
}
//ErrorDump example: xerrors 打印堆栈信息
func ErrorDump() {
err := foo1()
fmt.Printf("%v\n", err)
fmt.Printf("%+v\n", err)
}
var myError = xerrors.New("myerror")
func foo() error {
return myError
}
func foo1() error {
return xerrors.Errorf("foo1 : %w", foo())
}
go 错误处理设计思考的更多相关文章
- 用thinkphp进行微信开发的整体设计思考
用thinkphp进行微信开发的整体设计思考 http://www.2cto.com/weixin/201504/388423.html 2015-04-09 0个评论 作者:明 ...
- Atitit. null错误的设计 使用Optional来处理null
Atitit. null错误的设计 使用Optional来处理null 然后,我们再看看null还会引入什么问题. 看看下面这个代码: String address = person.getCount ...
- 2018.8.3 Java中容易犯错误的问题思考与总结
Java容易犯错误的问题思考 float型 float f = 3.4 是否正确 不正确,应该用强制类型转换.如下所示:float f = (float)3.4 或float f = 3.4f 在ja ...
- Java实现本地小数据量缓存尝试与实践&设计思考
话不多说先贴代码 /** * 缓存工具 */ public class ConcurrentHashMapCacheUtils{ /** * 当前缓存个数 */ public static Integ ...
- 深究带PLL的错误复位设计
PLL复位通常犯的错误 或者是像上一篇文章 FPGA知识大梳理(四)FPGA中的复位系统大汇总 中的图一样,也是错误设计.为何呢?看ALTPLL (Phase-Locked Loop) IP Cor ...
- Extjs的架构设计思考,单页面应用 or 多页面?
写在前面:不要认为 EXTJS 高版本就是一个界面改良,在项目中,仍然用 N 张页面,在 N 张页面部署 EXTJS .这种方式不用多讲,效率问题大家都看得出来, EXTJS 是一个集成开发工具,注定 ...
- RESTful API 设计思考
RESTful API 设计思考,内容来源网络加自己的思考 1.RESTful Web API采用面向资源的架构:同一的接口,所以其成员体现为针对同一资源的操作2.SOAP Web API采用RPC风 ...
- 比原链设计思考: 扩展性UTXO模型
用户模型是比原链在最初就需要确定的重要数据结构, 团队的选择还是聚焦在两种典型的模型系统中,Account模型和UTXO模型,和其他大多数区块链设计一样, 选择了模型就决定了协议层的重要实现,两种模型 ...
- 游戏设计思考:对COK的理解和思考
转自:http://www.gameres.com/804983.html 一.前言 发此文的起因是最近加入了一个游戏研究群,受到大家对游戏研究热情的感染,也想将自己对游戏的理解和感悟发出来和大家一起 ...
随机推荐
- shiro的使用与JWT整合
一.shiro入门 两大框架对比:安全框架Shiro和SpringSecurity的比较 了解shiro 什么是Shiro Apache Shiro是一个Java的安全(权限)框架.| Shiro可以 ...
- 小程序 rich-text 处理显示
VIEW <view class="richText"> <rich-text nodes="{{richTextHTML}}" bindta ...
- 数据结构与算法——迪杰斯特拉(Dijkstra)算法
tip:这个算法真的很难讲解,有些地方只能意会了,多思考多看几遍还是可以弄懂的. 应用场景-最短路径问题 战争时期,胜利乡有 7 个村庄 (A, B, C, D, E, F, G) ,现在有六个邮差, ...
- 使用vxe table组件时,edit-render配置$select',选中option后关闭cell的激活状态,显示选中option的value问题
在我的项目中使用vxe table组件时,edit-render配置{name: '$select', options: [{label:"脉搏",value:"maib ...
- 10.6.2 sendfile
1.传统Linux中 I/O 的问题 2.传统的 Linux 系统的标准 I/O 接口( read. write)是基于数据拷贝的,也就是数据都是 copy_to_user 或者 copy_from_ ...
- 那些我用Windows时必备的软件
那些我用Windows时必备的软件 使用Windows多年来,自己发现了许多不错的小软件,在此做一个备份清单,方便今后装新机. 起源 \(hadow\)ock$ 越过高墙的小飞机 Google Chr ...
- Firewalls文件配置防火墙
1.源文件 /usr/lib/firewalld/services 2.文件配置 cat /etc/firewalld/zones/public.xml <?xml version=" ...
- 国内首篇云厂商 Serverless 论文入选全球顶会:突发流量下,如何加速容器启动?
作者 | 王骜 来源 | Serverless 公众号 导读 USENIX ATC (USENIX Annual Technical Conference) 学术会议是计算机系统领域的顶级会议,入 ...
- bzoj1407,洛谷2421 NOI2002荒岛野人
题目大意: 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,-,M.岛上住着N个野人,一开始依次住在山洞C1,C2,-,CN中,以后每年,第i个野人会沿顺时针向前走P ...
- maven指令安装jar包到本地仓库
在项目配置过程中,偶尔会遇到jar包下载不来的情况,而同事又有相应的jar包,那么就可以通过maven安装指令直接将jar包安装到自己的本地仓库了. 安装指令: mvn install:install ...