如何实现堆栈跟踪?

huangapple go评论73阅读模式
英文:

How to implement stack tracing?

问题

我正在尝试实现堆栈错误追踪。我在追踪错误时遇到了困难。以下代码捕获了数据库错误,但没有追踪错误:

// err 表示 *db.Error
if err != nil {
  return nil, errors.Wrap(err, "error msg")
}

// 现在,在错误中间件中:
func traceError(err error) {
    _, ok := err.(stackTracer)
    if ok {
        fmt.Print("tracer implemented")
    } else {
        fmt.Print("tracer not implemented")
    }
}
switch e := errors.Cause(err).(type) {
  case *db.Error:
    fmt.Print("caught db error")
    traceError(err)
  default:
    fmt.Print("unknown error")
    traceError(err)
}

输出结果:

caught db error
tracer not implemented

当我创建新的错误时,追踪被实现了:

// err 表示 *db.Error
if err != nil {
  newError := errors.New(err.Error())
  return nil, errors.Wrap(newError, "error msg")
}

输出结果:

unknown error
tracer implemented

我期望的输出是:

caught db error
tracer implemented

编辑: 重新查看后,我发现我的代码运行正常。可能是我在代码的某个地方搞错了什么。

英文:

I am trying to implement stack error tracing. I am having difficulty tracing the error. The following code catches the db error. But it doesn’t trace the error:

// err represents *db.Error
if err != nil {
  return nil, errors.Wrap(err, "error msg")
}

// Now, in the error middleware:
func traceError(err error) {
	_, ok := err.(stackTracer)
	if ok {
		fmt.Print("tracer implemented")
	} else {
		fmt.Print("tracer not implemented")
	}
}
switch e := errors.Cause(err).(type) {
  case *db.Error:
    fmt.Print("caught db error")
    traceError(err)
  defaut:
    fmt.Print("unknown error")
    traceError(err)
}

Outputs:

caught db error
tracer not implemented

When I create new error the trace is implemented:

// err represents *db.Error
if err != nil {
  newError := errors.New(err.Error())
  return nil, errors.Wrap(newError, "error msg")
}

Outputs:

unknown error
tracer implemented

My desired output is:

caught db error
tracer implemented

Edit: After re-looking I found my code is working fine. I might have messed something somewhere in my code.

答案1

得分: 2

刚刚注意到问题中提到了github.com/pkg/errors包。除了问题中的一些语法错误外,它按预期工作:

package main

import (
	"fmt"
	"io/fs"
	"os"

	"github.com/pkg/errors"
)

func fn() error {
	_, err := os.Open("non-existing")
	if err != nil {
		return errors.Wrap(err, "fn")
	}

	return nil
}

type stackTracer interface {
	StackTrace() errors.StackTrace
}

func traceError(err error) {
	_, ok := err.(stackTracer)
	if ok {
		fmt.Println("tracer implemented")
	} else {
		fmt.Println("tracer not implemented")
	}
}

func main() {
	err := fn()

	switch e := errors.Cause(err); e.(type) {
	case *fs.PathError:
		fmt.Println("caught fs error")
		traceError(err)
	default:
		fmt.Println("unknown error")
		traceError(err)
	}
}

输出结果为:

caught fs error
tracer implemented
英文:

Just noticed that the question is talking about the package github.com/pkg/errors. Except for some syntax error in the question, it works as expected:

package main

import (
	"fmt"
	"io/fs"
	"os"

	"github.com/pkg/errors"
)

func fn() error {
	_, err := os.Open("non-existing")
	if err != nil {
		return errors.Wrap(err, "fn")
	}

	return nil
}

type stackTracer interface {
	StackTrace() errors.StackTrace
}

func traceError(err error) {
	_, ok := err.(stackTracer)
	if ok {
		fmt.Println("tracer implemented")
	} else {
		fmt.Println("tracer not implemented")
	}
}

func main() {
	err := fn()

	switch e := errors.Cause(err); e.(type) {
	case *fs.PathError:
		fmt.Println("caught fs error")
		traceError(err)
	default:
		fmt.Println("unknown error")
		traceError(err)
	}
}

The output is:

caught fs error
tracer implemented

huangapple
  • 本文由 发表于 2023年5月3日 17:13:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76162208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定