diff --git a/error.go b/error.go index bed9d7c..76b8659 100644 --- a/error.go +++ b/error.go @@ -1,24 +1,15 @@ package qerror import ( - "fmt" - "runtime" - "time" "bytes" + "runtime" "strconv" + "time" ) -type QBitError interface { - error - Stacktrace() []CallerInfo - Dt() time.Time -} - -type qbitError struct { - dt time.Time - message string - messageArgs []interface{} - stacktrace []CallerInfo +type BaseError struct { + dt time.Time + stacktrace []CallerInfo } type CallerInfo struct { @@ -27,11 +18,9 @@ type CallerInfo struct { FuncName string } -func New(message string, a ...interface{}) QBitError { - e := &qbitError{ - dt: time.Now(), - message: message, - messageArgs: a, +func New(offset int) *BaseError { + e := &BaseError{ + dt: time.Now(), } var ( @@ -39,7 +28,7 @@ func New(message string, a ...interface{}) QBitError { ok bool info CallerInfo ) - for i := 1; ; i++ { + for i := 1 + offset; ; i++ { pc, info.File, info.Line, ok = runtime.Caller(i) if !ok { break @@ -56,10 +45,11 @@ func New(message string, a ...interface{}) QBitError { return e } -func (e *qbitError) Error() string { +func (e *BaseError) Error() string { buf := &bytes.Buffer{} - fmt.Fprintf(buf, e.message, e.messageArgs...) + buf.WriteString("DateTime: ") + buf.WriteString(e.dt.String()) buf.WriteString("\nStacktrace:") for _, caller := range e.stacktrace { buf.WriteByte('\n') @@ -74,10 +64,10 @@ func (e *qbitError) Error() string { return buf.String() } -func (e *qbitError) Stacktrace() []CallerInfo { +func (e *BaseError) Stacktrace() []CallerInfo { return e.stacktrace } -func (e *qbitError) Dt() time.Time { +func (e *BaseError) Dt() time.Time { return e.dt } diff --git a/error_test.go b/error_test.go index 4ab95b8..b190a9e 100644 --- a/error_test.go +++ b/error_test.go @@ -7,9 +7,9 @@ import ( ) func TestNew(t *testing.T) { - err := New("Test message %d", 1) + err := New(0) - assert.Regexp(t, `^Test message 1\nStacktrace:\n\tgithub.com/go-qbit/qerror.TestNew at .+?/github.com/go-qbit/qerror/error_test.go:\d+\n`+ + assert.Regexp(t, `^DateTime: .+?\nStacktrace:\n\tgithub.com/go-qbit/qerror.TestNew at .+?/github.com/go-qbit/qerror/error_test.go:\d+\n`+ `\ttesting.tRunner at .+?/testing/testing.go:\d+`, err.Error()) stacktrace := err.Stacktrace() @@ -20,3 +20,16 @@ func TestNew(t *testing.T) { assert.NotZero(t, err.Dt()) } + +func TestErrorf(t *testing.T) { + err := Errorf("test %s", "message") + + assert.Regexp(t, `^test message\nDateTime: .+?\nStacktrace:\n\tgithub.com/go-qbit/qerror.TestErrorf at .+?/github.com/go-qbit/qerror/error_test.go:\d+\n`+ + `\ttesting.tRunner at .+?/testing/testing.go:\d+`, err.Error()) + + stacktrace := err.Stacktrace() + assert.Len(t, stacktrace, 3) + assert.Regexp(t, `.+/github.com/go-qbit/qerror/error_test.go$`, stacktrace[0].File) + assert.NotZero(t, stacktrace[0].Line) + assert.Equal(t, "github.com/go-qbit/qerror.TestErrorf", stacktrace[0].FuncName) +} diff --git a/text.go b/text.go new file mode 100644 index 0000000..b0eecdd --- /dev/null +++ b/text.go @@ -0,0 +1,25 @@ +package qerror + +import ( + "bytes" + "fmt" +) + +type TextError struct { + *BaseError + message string + messageArgs []interface{} +} + +func Errorf(message string, a ...interface{}) *TextError { + return &TextError{New(1), message, a} +} + +func (e *TextError) Error() string { + buf := &bytes.Buffer{} + buf.WriteString(fmt.Sprintf(e.message, e.messageArgs...)) + buf.WriteByte('\n') + buf.WriteString(e.BaseError.Error()) + + return buf.String() +}