如果将所有错误更改为包括文件名,函数名和行号的样式,是否有潜在的问题?

The primary purpose is to facility debugging and make error log more useful,but It is a big change,so I want to know:any poptential problem?

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"))
}

You can see a similar approach in the project youtube/vitess/go/tb/error.go, but it checks if one of the arguments provided with an new Error already includes a stack:

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

Another simpler approach is illustrated in this gist: take an existing error (instead of defining a new type), and add/print the stack information to it.

// 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
", filename, callingFuncName, line, msg, err)
            os.Exit(1)
        }
    }
}