自定义错误需捕获堆栈信息以提升调试效率,可通过实现包含消息和调用栈的结构体,利用runtime.Callers和FuncForPC获取帧信息,或使用github.com/pkg/errors等库简化操作。

在Go语言中,创建带有堆栈信息的自定义错误可以极大提升调试效率,尤其是在复杂调用链中定位问题时。标准库的
error
Go原生的
errors.New
fmt.Errorf
%w
errors
要获得堆栈信息,需要借助
runtime
github.com/pkg/errors
我们可以定义一个结构体,包含错误消息和堆栈信息:
立即学习“go语言免费学习笔记(深入)”;
// stackError.gopackage main
import (
"fmt"
"runtime"
"strings"
)
type stackError struct {
msg string
stack []uintptr // 存储函数调用地址
}
func (e *stackError) Error() string {
return e.msg
}
func (e *stackError) StackTrace() []string {
var frames []string
for _, pc := range e.stack {
fn := runtime.FuncForPC(pc)
if fn == nil {
frames = append(frames, "unknown")
} else {
file, line := fn.FileLine(pc)
frames = append(frames, fmt.Sprintf("%s:%d %s", file, line, fn.Name()))
}
}
return frames
}
func newStackError(msg string) *stackError {
pc := make([]uintptr, 32)
n := runtime.Callers(2, pc) // 跳过 runtime.Callers 和 newStackError 本身
return &stackError{
msg: msg,
stack: pc[:n],
}
}
在实际调用中使用自定义错误:
func doSomething() error {
return newStackError("something went wrong")
}
func main() {
if err := doSomething(); err != nil {
fmt.Println("Error:", err)
if se, ok := err.(*stackError); ok {
fmt.Println("Stack trace:")
for _, frame := range se.StackTrace() {
fmt.Println("\t", frame)
}
}
}
}
运行后会输出错误信息和完整的调用堆栈,帮助快速定位错误来源。
虽然手动实现有助于理解原理,但在生产环境中推荐使用成熟的库,例如
github.com/pkg/errors
import "github.com/pkg/errors"
err := errors.New("database connection failed")
err = errors.Wrap(err, "failed to initialize service")
通过
errors.Print(err)
%+v
现代Go(1.13+)也支持
errors.Unwrap
errors.Is
errors.As
%w
基本上就这些。自定义错误加堆栈的关键是捕获调用帧并格式化输出,手动实现可控但繁琐,第三方库更高效实用。
以上就是Golang如何创建自定义错误 实现带有堆栈信息的错误类型的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号