多层抽象中的错误传播
在 Go 中,跨多个抽象级别的错误处理可能会成为一个挑战,因为需要不断向上传递错误。这通常会导致重复的日志消息或丢失上下文信息。
推荐解决方案:错误注释
错误处理的首选方法是按原样注释错误通过不同的抽象级别。这允许保留原始错误的上下文,同时在每个级别添加附加信息。
使用像“github.com/pkg/errors”这样的库,错误处理可以实现为如下:
// Wraps the original error with additional context. func (o *ObjectOne) CheckValue() error { if o.someValue == 0 { return errors.New("Object1 illegal state: value is 0") } return nil } // Annotates the original error with context. func (oT *ObjectTwoHigherLevel) CheckObjectOneIsReady() error { if err := oT.objectOne.CheckValue(); err != nil { return errors.Wrap(err, "Object2 illegal state: Object1 is invalid") } return nil } // Preserves the annotated error stack. func (oTh *ObjectThreeHiggerLevel) CheckObjectTwoIsReady() error { if err := oTh.ObjectTwoHigherLevel.CheckObjectOneIsReady(); err != nil { return errors.Wrap(err, "Object3 illegal state: Object2 is invalid") } return nil }
用法:
o3 := &ObjectThreeHiggerLevel{} if err := o3.CheckObjectTwoIsReady(); err != nil { fmt.Println(err) }
输出:
Object3 illegal state: Object2 illegal state: Object1 illegal state: value is 0
这种方法提供了一个干净的信息丰富的错误处理机制,避免重复记录并保留上下文信息。
替代方案:错误扩展
为了简单起见,另一种方法是使用附加上下文来扩展原始错误fmt.Errorf():
func (o *ObjectOne) CheckValue() error { if o.someValue == 0 { return fmt.Errorf("Object1 illegal state: value is %d", o.someValue) } return nil }
用法:
o3 := &ObjectThreeHiggerLevel{} if err := o3.CheckObjectTwoIsReady(); err != nil { fmt.Println(err) }
输出:
Object3 illegal state: Object2 illegal state: Object1 illegal state: value is 0
这个方法不如错误注释通用,但实现起来更简单。
以上是如何有效处理多层 Go 抽象中的错误传播?的详细内容。更多信息请关注PHP中文网其他相关文章!