Last active
August 29, 2015 13:58
-
-
Save arnehormann/9971168 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mysql | |
import ( | |
"errors" | |
"fmt" | |
"runtime" | |
"time" | |
) | |
var trace = false | |
type traceErr struct { | |
File string | |
Line int | |
Time time.Time | |
Err error | |
} | |
func newError(err error, stackdepth int) *traceErr { | |
now := time.Now() | |
_, file, line, _ := runtime.Caller(stackdepth) | |
// shorten filename like "log" does | |
short := file | |
for i := len(file) - 1; i > 0; i-- { | |
if file[i] == '/' { | |
short = file[i+1:] | |
break | |
} | |
} | |
return &traceErr{ | |
File: short, | |
Line: line, | |
Time: now, | |
Err: err, | |
} | |
} | |
func Error(err error) error { | |
if err == nil || !trace { | |
return err | |
} | |
if _, isTraced := err.(*traceErr); isTraced { | |
return err | |
} | |
return newError(err, 2) | |
} | |
func ErrString(str string) error { | |
err := errors.New(str) | |
if trace { | |
return newError(err, 2) | |
} | |
return err | |
} | |
func ErrStringf(format string, args ...interface{}) error { | |
err := fmt.Errorf(format, args...) | |
if trace { | |
return newError(err, 2) | |
} | |
return err | |
} | |
func (err *traceErr) Error() string { | |
return err.Err.Error() | |
} | |
func (err *traceErr) String() string { | |
return fmt.Sprintf( | |
"%s %s:%d - %s", | |
err.Time.Format(time.RFC3339), | |
err.File, | |
err.Line, | |
err.Error(), | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A regular error as is. When setting
trace = true
, the errors can be used as a string:The string will look like
2006-01-02T15:04:05Z07:00 source.go:13 - error message
and will include the filename and line number from wherever
Error
,ErrString
orErrStringf
were originally called.It's like log, but wraps errors directly.
If errors are returned anyway, wrapping them inside the nil-check-if
should be negligable performance wise.
But the error can be serialized in a pretty way and provides a lot more information if it's passed around to another subsystem or even over the network. For intensive use, it should be exported. I just didn't want to pollute the namespace in my scenario.