error-handling - 如果将所有错误都改为包含文件名、函数名和行号的样式,会出现什么潜在问题吗?

标签 error-handling go

主要目的是方便调试并使错误日志更有用,但这是一个很大的变化,所以我想知道:有什么潜在的问题吗?

package main

import(
    "errors"
    //"fmt"
    "runtime"
    "github.com/fatih/structs"
    "github.com/Sirupsen/logrus"
)

type Error interface {
    Mapify() map[string]interface{}

    Error() string
}

func New(err error) Error {
    //get error runtime info
    pc, file, line, _ := runtime.Caller(1)
    funcName := runtime.FuncForPC(pc).Name()

    return &ErrorString{err.Error(), file, funcName, line}
}

type ErrorString struct {
    Err               string
    File              string//file name
    Func               string//function name
    Line              int
}

func (s *ErrorString) Mapify() map[string]interface{} {
    return structs.Map(s)
}

func (s *ErrorString) Error() string {
    return s.Err
}

func main(){
    logrus.WithFields(logrus.Fields(throw().Mapify())).Error(errors.New("test"))
}

func throw() Error{
    return New(errors.New("any error"))
}

最佳答案

可以在项目youtube/vitess/go/tb/error.go中看到类似的做法,但它会检查新错误提供的参数之一是否已包含堆栈:

func Errorf(msg string, args ...interface{}) error {
    stack := ""
    // See if any arg is already embedding a stack - no need to
    // recompute something expensive and make the message unreadable.
    for _, arg := range args {
        if stackErr, ok := arg.(stackError); ok {
            stack = stackErr.stackTrace
            break
        }
    }
    // compute own stack if empty

this gist 中说明了另一种更简单的方法。 :获取现有错误(而不是定义新类型),并向其添加/打印堆栈信息。

// Handle an error for any function at <depth> from the top of the call stack
func HandleDepth(msg string, err error, depth int) {
    // If the error is non-nil
    if err != nil {
        // Find out who called it and where from, skip the top <depth> calls
        pc, file, line, ok := runtime.Caller(depth)
        // Parse out the filename and calling function
        filename := filepath.Base(file)
        callingFunc := runtime.FuncForPC(pc)
        callingFuncName := callingFunc.Name()
        // If we could retrieve the information then print a message and exit with an error
        if ok {
            fmt.Printf("%s:%s:%d: %s %s\n", filename, callingFuncName, line, msg, err)
            os.Exit(1)
        }
    }
}

关于error-handling - 如果将所有错误都改为包含文件名、函数名和行号的样式,会出现什么潜在问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27467846/

相关文章:

go - 正确的惯用字节缓冲区读写

go - 如何在接口(interface)上调用 len()?

vb.net - 在VB中添加错误处理程序

error-handling - 应用程序应该崩溃还是在注意到问题的同时继续正常运行?

windows - Powershell脚本中的通用故障错误

c - write(2) 失败怎么办?

php - 为什么 MAMP 不显示错误?

go - 如何使用带有密码的 SSH key 身份验证 `go get` 私有(private)仓库

go - 如何使用库对象?

go - sync.WaitGroup - 为什么在 .wait() 之后出现一个 go 例程