0
点赞
收藏
分享

微信扫一扫

Error

guanguans 05-14 23:30 阅读 4

1.为什么errors.New返回指针

1.1errors.new()源码查看

Go error就是一个接口。

我们经常使用errors.new()来返回一个error对象的指针

Error_堆栈

Error_json_02

基础库中有大量自定义的error

Error_堆栈_03

1.2为什么errors.New要返回对象的指针

避免当两个err进行相等判断时出现问题

Error_json_04

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

Error_java_05

预定义err问题

1.调用者需要使用==将err与预先声明的err进行比较

2.当使用者使用fmt.Errorf携带一些上下文后,会破坏调用者的==,调用者需要通过error.Error()进行判断

3.依赖error.Error输出不好,如果包的提供者修改了相关内容,程序会出现问题。

Error_堆栈_06

3.2Error type

Error type解析

Error type是实现了error接口的自定义类型。

这种方式的一大改进是能够包装底层错误提供更多的上下文。

Error_java_07

Error type举例

通过类型断言和类型switch来判断err

Error_java_08

3.3不透明的错误处理--opague errors

这里的关键是,这个逻辑可以在不了解err的底层类型的情况下实现,我们只对它的行为感兴趣

Error_json_09

4.Wrap Error

4.1warp err介绍

1.使用errors.Wrap()或errors.Wrapf()保留堆栈信息

2.使用errors.Cause()获取原始错误类型,再进行sentinel error判定

3.使用errors.WithMessage()携带上下文信息

4.使用%T打印原始错误类型

5.使用%+v打印堆栈信息

Error_json_10

Error_java_11

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方法,如下示例

Error_java_12

自己写一个

Error_java_13

5.2与pkg/errors wrap对比

%w还是不包含堆站信息。

wrap即包含堆站信息,又兼容errors.Is及errors.As,还是wrap支持的好些。

Error_堆栈_14


Error_json_15

举报
0 条评论