package lerror import ( "fmt" "os" "path/filepath" "runtime" ) var ( lenBasePath int = 0 ) func init() { path, err := os.Executable() if err != nil { path = "" } lenBasePath = len(filepath.Dir(path)) } type Error struct { msg string trace []string } func NewString(msg string) *Error { return &Error{ msg: msg, trace: []string{trace()}, } } func NewError(err error) *Error { return &Error{ msg: err.Error(), trace: []string{trace()}, } } func (it *Error) Add(msg string) *Error { it.trace = append(it.trace, trace()) it.msg = msg + ": " + it.msg return it } func (it *Error) String() string { result := it.msg for _, line := range it.trace { result += "\n" + line } return result } func trace() string { _, file, line, ok := runtime.Caller(2) if !ok { return "not possible to recover the information" } if lenBasePath < len(file) { return fmt.Sprintf("%s:%d", file[lenBasePath:], line) } else { return fmt.Sprintf("%s:%d", file, line) } }