【Go进阶】02 错误处理

目录

1. 错误处理

1.1. Error VS Exception

  1. Error概述
    1. 对于真正意外的情况, 那些表示不恢复的程序错误; 例如索引越界, 不可恢复的环境问题, 栈溢出, 才使用panic;
    2. 对于其他错误情况, 使用error来进行判定;
      1. 简单;
      2. 没有隐藏的控制流;
      3. 考虑失败, 而不是成功;
      4. 完全交给你来控制error;
      5. error are values
import "errors"
errors.New()  返回的是 内部errorString对象的指针;
errors.New("package: content ")

1.2. Error Type(错误类型)

1.2.1. Sentinel Error

预定义的特定错误; --来源于计算机编程中的使用一个特定值来表示不可能进一步处理的做法;

  1. 语法
if err==ErrSomething {...}
类似的io.EOF, 更底层的syscalll.ENOENT;

  1. 特性
    1. 是最不灵活的错误处理策略, 因为返回不同的错误将破坏相等性检查;
    2. 不要依赖 error.Error 的输出; – 存在不要是方便程序员使用, 但不是程序使用(编写测试程序坑会依赖这个返回),
      输出的字符串用于记录日志, 输出到stdout;
    3. Sentinel errors在两个包之间创建了依赖; – 最糟糕的问题;
    4. 结论: 尽可能避免 sentinel errors;

1.2.2. Error types

  • MyError是一个type, 可以使用断言转换成这个类型, 来获取更多的上下文信息;

    1. 与错误值相比, 错误类型能够包装底层错误来提供更多的上下文;
    2. 例: os.PathError
      type PathError struct {
         op string
         Path string
         Err error
      }
      
  • 调用者要使用类型断言和类型switch, 就要让自定义的error变为public, 这种模型会导致和调用者产生强耦合, 从而导致api变得脆弱;

  • 结论: 尽量避免使用error types,

1.2.3. opaque errors

  • 最灵活的错误戳晒出策略, 代码合调用者之间的耦合最少;–不透明的错误处理; – 只需要返回错误儿不假设内容;

  • 可以进一步断言: 错误实现了特定的行为, 而不是断言错误是特定的类型或值;


1.3. wrap

  1. 概述

    1. Error Wrapping,提供了可以一个error嵌套另一个error功能,好处就是我们可以根据嵌套的error序列,生成一个error错误跟踪链,也可以理解为错误堆栈信息,
    2. 可以便于我们跟踪调试,哪些错误引起了什么问题,根本的问题原因在哪里。
    3. 因为error可以嵌套,所以每次嵌套的时候,我们都可以提供新的错误信息,并且保留原来的error。
    e := errors.New("原始错误e")
    w := fmt.Errorf("Wrap了一个错误%w", e)
    

Golang并没有提供什么Wrap函数,而是扩展了fmt.Errorf函数,加了一个%w来生成一个可以Wrapping Error,通过这种方式,我们可以创建一个个以Wrapping Error。
Go语言(golang)新发布的1.13中的Error Wrapping深度分析

参考:

  1. Go语言(golang)新发布的1.13中的Error Wrapping深度分析

2. 日志输出

2.1. 日志框架

  • 日志框架推荐
    • logrus : https://github.com/sirupsen/logrus
    • seelog:https://github.com/cihub/seelog

3. 异常处理


3.1. 错误处理概述

io.EOF是io包中的变量, 表示文件结束的错误:

  • panic()

    1. 谨慎使用 panic() 抛出异常, 如果没有捕获异常, 将会导致程序异常退出;
    2. panic() 发生前注册的defer, 会在panic() 之前 执行;
    3. 异常 可以直接调用 panic() 产生, 也可以有运行时的错误产生;(如: 越界访问数组)
  • recover()

    1. 该函数可以让 宕机流程中的 goroutine 恢复过来;
    2. 注意:
      1. 仅在 defer 中有效;
      2. 当前 goroutine 陷入panic, 调用recover() 可以捕捉panic的输入值, 并恢复到正常执行;
         1. recover 只有在 defer 调用的函数内部时,
             才能阻止 panic 抛出的异常信息继续向上传递;
      3. 延迟调用中引发的错误, 可被后续延迟调用捕获, 但仅 `最后一个错误可被捕获`;
      4. 任何未捕获的错误都会沿调用堆栈向外传递。
      
    3. go 语言中的recover() 的宕机恢复机制就对应其他语言中的 try/catch 机制;

参考:

  1. Go 学习笔记(19)— 函数(05)[如何触发 panic、触发 panic 延迟执行、panic 和 recover 的关系]

3.2. panic

  1. defer的执行机制

3.3. recover


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值