1.为什么errors.New返回指针
1.1errors.new()源码查看
Go error就是一个接口。
我们经常使用errors.new()来返回一个error对象的指针。
基础库中有大量自定义的error
1.2为什么errors.New要返回对象的指针
避免当两个err进行相等判断时出现问题
2.Error and Exception
2.1多语言对比
go处理异常的逻辑没有引入exception,支持多参数返回。
Go中有Panic机制,Panic与其他语言的exception不同,Panic是fatal error,程序直接终止服务,使用需谨慎。
python中--try except
"1.异常类只能用来处理指定的异常情况,如果非指定异常则无法处理"
s1 = 'hello'
try:
int(s1)
except IndexError as e: # 未捕获到异常,程序直接报错
print e
Java中try--catch
// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{
public static void main(String args[]){
try{
int a[] = new int[2];
System.out.println("Access element three :" + a[3]);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Exception thrown :" + e);
}
System.out.println("Out of the block");
}
}
Go中Err
package main
import (
"encoding/json"
"fmt"
)
func main() {
_,err :=json.Marshal("string")
if err!=nil{
fmt.Println(err)
}
}
3.Error类型
3.1预定义的错误--sentinel Error
预定义err举例
这些内部定义好的err都是预定义err
预定义err问题
1.调用者需要使用==将err与预先声明的err进行比较
2.当使用者使用fmt.Errorf携带一些上下文后,会破坏调用者的==,调用者需要通过error.Error()进行判断
3.依赖error.Error输出不好,如果包的提供者修改了相关内容,程序会出现问题。
3.2Error type
Error type解析
Error type是实现了error接口的自定义类型。
这种方式的一大改进是能够包装底层错误提供更多的上下文。
Error type举例
通过类型断言和类型switch来判断err
3.3不透明的错误处理--opague errors
这里的关键是,这个逻辑可以在不了解err的底层类型的情况下实现,我们只对它的行为感兴趣
4.Wrap Error
4.1warp err介绍
1.使用errors.Wrap()或errors.Wrapf()保留堆栈信息
2.使用errors.Cause()获取原始错误类型,再进行sentinel error判定
3.使用errors.WithMessage()携带上下文信息
4.使用%T打印原始错误类型
5.使用%+v打印堆栈信息
4.2err使用方式
1.在我们自己的逻辑中,使用errors.New或errors.Errorf返回错误
2.调用其他包内的函数,err直接返回
3.如果使用其他库,例如 os、net等,可以考虑使用errors.Wrap或errors.Wrapf保存堆栈信息
4.直接返回错误,而不是每个错误产生的地方都打印日志。
5.在程序的顶部(controller处)或goroutine顶部,使用%+v打印堆栈详情。
6.使用errors.Cause获取root error,在进行sentinel error判定。
7.使用errors.withMessage()携带上下文信息。
5.go1.13提供特性
5.1 1.13err介绍
go1.13 errors包,包含两个用于检查错误的新函数:Is和As。
fmt.Errorf支持通过%w包装err,这种err可用于errors.Is及errors.As判断。
err要实现Unwrap方法,如下示例
自己写一个
5.2与pkg/errors wrap对比
%w还是不包含堆站信息。
wrap即包含堆站信息,又兼容errors.Is及errors.As,还是wrap支持的好些。