我正在尝试使用 go-errors 来包含我生成的错误的堆栈跟踪。我有一个自定义
HttpError
类型,我也想包含堆栈跟踪。我最初的想法是通过嵌入来做到这一点,但我似乎无法嵌入它,因为类的名称 (Error
) 与其中一个方法的名称相同。
package netutil
import (
"github.com/go-errors/errors"
)
type HttpError struct {
status int
*errors.Error
}
func (h *HttpError) Error() string {
return "Failed"
}
func NewHttpError(status int, message string) *HttpError {
return &HttpError{
status,
errors.New(message),
}
}
我收到以下错误:
tmp_error.go:12: type HttpError has both field and method named Error
有什么建议吗?
为什么不直接用适当的名称来命名这个内部错误,例如
inner-error
或 stack-trace
?
type HttpError struct {
status int
StackTace *errors.Error
}
在其他语言/框架(如 .NET 和 Java)中用于错误处理的类中似乎是相当常见的做法。
另一种选择是在创建错误时使用
fmt.Sprintf
将自定义消息与内部错误连接起来,将其全部保留为一个。
errors.New(fmt.Sprintf("This proprietary error happened! Stack trace: %s", message))
;
如果你这样做了,你就不会实现
func (h *HttpError) Error()
,因为你将依赖于嵌入的错误。
自从提出这个问题以来,Go 错误模式已经发生了很大的变化。现在有一种“将错误包装成新错误的标准方法”,并带有潜在的附加信息。然后,像 gitlab.com/tozd/go/errors
这样的包(免责声明:我是它的维护者)会使用它来添加附加信息,例如堆栈跟踪或结构化详细信息。所以你的例子可能看起来像:
package netutil
import (
"gitlab.com/tozd/go/errors"
)
type HttpError struct {
status int
}
func (h *HttpError) Error() string {
return "Failed"
}
func NewHttpError(status int, message string) error {
return errors.WithMessage(&HttpError{status}, message)
}
errors.WithMessage
将
message
添加到 HttpError
错误的错误消息之前,并记录堆栈跟踪(如果错误还没有堆栈跟踪,则 HttpError
没有)。您可以格式化错误以获取堆栈跟踪:fmt.Printf("%+v\n", err)