从Go 1.13开始,我们可以链接错误,解开错误并通过errors.Is()
和errors.As()
检查链接中的任何错误是否与预期错误相符。
要包裹一个错误,您要做的就是如下使用%w
动词和fmt.Errorf()
。
fmt.Errorf("Custom message: %w", err)
这很容易,它会将err
包裹在另一个消息中,并附加一条消息。但是,可以说我需要的不仅仅是消息,而是更多的上下文。如何在自己的结构化自定义错误中包装err
?仅使用Go 1.13+标准库。
答案 0 :(得分:2)
您可以创建一个新的错误类型,该错误类型可以包装其他错误,同时提供其他结构化信息。
type MyError struct {
Inner error
// Provide any additional fields that you need.
Message string
AdditionalContext string
}
// Error is mark the struct as an error.
func (e *MyError) Error() string {
return fmt.Sprintf("error caused due to %v; message: %v; additional context: %v", e.Inner, e.Message, e.AdditionalContext)
}
// Unwrap is used to make it work with errors.Is, errors.As.
func (e *MyError) Unwrap() error {
// Return the inner error.
return e.Inner
}
// WrapWithMyError to easily create a new error which wraps the given error.
func WrapWithMyError(err error, message string, additionalContext string) error {
return &MyError {
Inner: err,
Message: message,
AdditionalContext: additionalContext,
}
}
您需要实现Error
和Unwrap
接口才能使用errors.Is
和errors.As
的新功能。
答案 1 :(得分:0)
错误是一个界面(error() string
满足),因此您可以将另一个错误类型设置为:
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
}