如何在 Go 中添加堆栈跟踪错误?

问题描述 投票:0回答:1

背景

我是 Go 新手,来自 C# 和 Java。所以返回错误的概念对我来说有点新。我已经习惯了,但我真的很怀念堆栈跟踪,它们在调试过程中非常有帮助。所以我正在考虑其他方法来包含我的错误的堆栈跟踪。

建议的替代方案

示例代码链接

一个

Error
结构体,包装了
error
和堆栈跟踪。

type Error struct {
    WrappedError error
    StackTrace   string
}

func (e *Error) Error() string {
    return e.WrappedError.Error()
}

func (e *Error) Join(errs ...error) {
    errs = append([]error{e.WrappedError}, errs...)
    e.WrappedError = errors.Join(errs...)
}

func NewError(msg string) *Error {
    return &Error{
        WrappedError: errors.New(msg),
        StackTrace:   string(debug.Stack()),
    }
}

调用代码看起来像这样,

func main() {
    result, err := Foo()
    if err != nil {
        fmt.Println(err.Error())
        fmt.Println()
        fmt.Println(err.StackTrace)
        return
    }
    fmt.Printf("result: %d", result)

}

func Foo() (int, *Error) {
    //some additional logic
    result, err := Bar()
    if err != nil {
        err.Join(errors.New("some msg from Foo level"))
        return 0, err
    }
    return result, nil
}

func Bar() (int, *Error) {
    //some additional logic
    if 1 == 1 {
        return 0, NewError("oops, something went wrong")
    }
    return 1, nil
}

这种方法允许我向我的

error
添加更多详细信息,同时还拥有所有现有功能。

问题

  1. 这种做法有错吗?
  2. 如果是错误的,建议将堆栈跟踪添加到我的错误中的方法是什么?
go error-handling
1个回答
0
投票

Go 使用 错误作为值,并且对于 处理错误 有非常清晰的想法。特别是在上一篇文章中,您可以看到如何使用附加上下文来包装错误,以便它们对于外层函数变得更有用。

一个核心原则是应该以编程方式处理错误,而堆栈跟踪对此没有用处。此外,堆栈跟踪可能没有帮助,因为它们不显示谁调用了您的 goroutine。如果堆栈跟踪和调试是理解错误发生原因的唯一方法,那么您应该考虑重构这部分代码。

还有其他机制可以了解程序的执行情况,例如飞行记录,您可以将其用于长时间运行的请求,因为错误中的堆栈跟踪并没有真正的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.