diff --git a/terror_error.go b/terror_error.go index ad48c99..4a8826b 100644 --- a/terror_error.go +++ b/terror_error.go @@ -61,7 +61,8 @@ type Error struct { codeText ErrCodeText // message is a template of the description of this error. // printf-style formatting is enabled. - message string + message string + defaultFmt bool // The workaround field: how to work around this error. // It's used to teach the users how to solve the error if occurring in the real environment. workaround string @@ -126,6 +127,12 @@ func (e *Error) Error() string { func (e *Error) GetMsg() string { if len(e.args) > 0 { + if e.defaultFmt { + args := make([]interface{}, 0, 1+len(e.args)) + args = append(args, e.message+": ") + args = append(args, e.args...) + return fmt.Sprint(args...) + } return fmt.Sprintf(e.message, e.args...) } return e.message @@ -147,6 +154,8 @@ func (e *Error) fillLineAndFile(skip int) { func (e *Error) GenWithStack(format string, args ...interface{}) error { err := *e err.message = format + // Always enable printf style message. + err.defaultFmt = false err.args = args err.fillLineAndFile(1) return AddStack(&err) @@ -165,6 +174,8 @@ func (e *Error) GenWithStackByArgs(args ...interface{}) error { func (e *Error) FastGen(format string, args ...interface{}) error { err := *e err.message = format + // Always enable printf style message. + err.defaultFmt = false err.args = args return SuspendStack(&err) } @@ -340,6 +351,12 @@ func MySQLErrorCode(code int) NormalizeOption { } } +func MessageDefaultFormat() NormalizeOption { + return func(e *Error) { + e.defaultFmt = true + } +} + // Normalize creates a new Error object. func Normalize(message string, opts ...NormalizeOption) *Error { e := &Error{ diff --git a/terror_test/terror_test.go b/terror_test/terror_test.go index eecd9e9..563b75f 100644 --- a/terror_test/terror_test.go +++ b/terror_test/terror_test.go @@ -162,3 +162,17 @@ func (*testTErrorSuite) TestWarpAndField(c *C) { errWithWarpedCause := errors.Annotate(ErrGetLeader, causeErr.Error()) c.Assert(errWithWarpedCause.Error(), Equals, "load from etcd meet error: [member:ErrGetLeader]fail to get leader") } + +func (*testTErrorSuite) TestMessageDefaultFormat(c *C) { + causeErr := errors.New("load from etcd meet error") + ErrGetLeader := errors.Normalize("fail to get leader", errors.RFCCodeText("member:ErrGetLeader"), errors.MessageDefaultFormat()) + + errAnnotate := errors.Annotate(ErrGetLeader, causeErr.Error()) + c.Assert(errAnnotate.Error(), Equals, "load from etcd meet error: [member:ErrGetLeader]fail to get leader") + + errFastGenByArgs := ErrGetLeader.FastGenByArgs(causeErr.Error()) + c.Assert(errFastGenByArgs.Error(), Equals, "[member:ErrGetLeader]fail to get leader: load from etcd meet error") + + errFastGen := ErrGetLeader.FastGen("caused by: %s", causeErr.Error()) + c.Assert(errFastGen.Error(), Equals, "[member:ErrGetLeader]caused by: load from etcd meet error") +}