• Error 封装

    Error 封装

    下面提供三种主要的方法来传递函数调用失败返回的错误:

    • 如果想要维护原始错误类型并且不需要添加额外的上下文信息,就直接返回原始错误。
    • 使用 "pkg/errors".Wrap 来增加上下文信息,这样返回的错误信息中就会包含更多的上下文信息,并且通过 "pkg/errors".Cause 可以提取出原始错误信息。
    • 如果调用方不需要检测或处理特定的错误情况,就直接使用 fmt.Errorf

    情况允许的话建议增加更多的上下文信息来代替诸如 "connection refused" 之类模糊的错误信息。返回 "failed to call service foo: connection refused" 用户可以知道更多有用的错误信息。

    在将上下文信息添加到返回的错误时,请避免使用 "failed to" 之类的短语以保持信息简洁,这些短语描述的状态是显而易见的,并且会随着错误在堆栈中的传递而逐渐堆积:

    BadGood
    1. s, err := store.New()
    2. if err != nil {
    3. return fmt.Errorf(
    4. "failed to create new store: %s", err)
    5. }
    1. s, err := store.New()
    2. if err != nil {
    3. return fmt.Errorf(
    4. "new store: %s", err)
    5. }
    1. failed to x: failed to y: failed to create new store: the error
    1. x: y: new store: the error

    但是,如果这个错误信息是会被发送到另一个系统时,必须清楚的表明这是一个错误(例如,日志中 err 标签或者 Failed 前缀)。

    另见 Don't just check errors, handle them gracefully。