Go 仅使用标准库,如何在自定义错误中包装错误?

Go 仅使用标准库,如何在自定义错误中包装错误?,go,error-handling,Go,Error Handling,自Go 1.13以来,我们能够通过errors.Is()和errors.As()链接错误、展开错误并检查链中的任何错误是否与任何预期错误匹配 要包装错误,只需使用%w动词和fmt.Errorf()如下所示 fmt.Errorf("Custom message: %w", err) 这很简单,它将err包装到另一个带有附加消息的文件中。但假设我需要更多的上下文,而不仅仅是一条信息。如何将err包装到我自己的结构化自定义错误中?仅使用Go 1.13+标准库。错误是一个接口(由错误()字符串满足),

自Go 1.13以来,我们能够通过
errors.Is()
errors.As()
链接错误、展开错误并检查链中的任何错误是否与任何预期错误匹配

要包装错误,只需使用
%w
动词和
fmt.Errorf()
如下所示

fmt.Errorf("Custom message: %w", err)
这很简单,它将
err
包装到另一个带有附加消息的文件中。但假设我需要更多的上下文,而不仅仅是一条信息。如何将
err
包装到我自己的结构化自定义错误中?仅使用Go 1.13+标准库。

错误是一个接口(由
错误()字符串满足),因此您可以将另一种错误类型设置为:

type myCustomError struct {
  Message    string
  StatusCode int
}

func (m myCustomError) error() string {
  return fmt.Sprintf("Code %d: \tMessage: %s", m.StatusCode, m.Message) 
}
现在,您可以使用作为自定义错误抛出的错误

_, err := doStuff()
var v myCustomError
if errors.As(err, &v) {
   // now v is parsed 
}

您可以创建一个新的错误类型,它在提供其他结构化信息的同时包装其他错误

键入MyError结构{
内部误差
//提供您需要的任何其他字段。
消息字符串
附加上下文字符串
}
//错误是将结构标记为错误。
func(e*MyError)Error()字符串{
返回fmt.Sprintf(“由于%v导致的错误;消息:%v;附加上下文:%v”,e.内部,e.消息,e.附加上下文)
}
//“展开”用于处理错误。is,errors.As。
func(e*MyError)展开()错误{
//返回内部错误。
返回e.内部
}
//WrapWithMyError可轻松创建一个新错误,该错误将封装给定的错误。
func WrapWithMyError(错误、消息字符串、附加上下文字符串)错误{
返回和MyError{
内心:呃,
讯息:讯息,,
AdditionalContext:AdditionalContext,
}
}

您需要实现
Error
Unwrap
接口,以使用
errors.Is
errors的新功能。由于

完美,这就是我想要的。此外,我还检查了std lib fmt.Errorf代码,它就是这样做的。它使用内部错误和展开方法创建结构。我希望展开方法是接口的一部分,但它似乎不是。展开是临时接口的一部分。我指的是经典的公开接口。我们没有具体的原因——他们找不出一个名字。问题不是关于创建客户错误,而是在自定义错误中包装现有错误以创建错误链,稍后可以使用errors.As和errors.Is函数检查该错误链。