diff --git a/errors/gerror/gerror.go b/errors/gerror/gerror.go index db141ef68..ce5bc0fc5 100644 --- a/errors/gerror/gerror.go +++ b/errors/gerror/gerror.go @@ -1,4 +1,4 @@ -// Copyright GoFrame gf Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -92,7 +92,7 @@ func Wrap(err error, text string) error { error: err, stack: callers(), text: text, - code: -1, + code: Code(err), } } @@ -107,7 +107,37 @@ func Wrapf(err error, format string, args ...interface{}) error { error: err, stack: callers(), text: fmt.Sprintf(format, args...), - code: -1, + code: Code(err), + } +} + +// WrapSkip wraps error with text. +// It returns nil if given err is nil. +// The parameter specifies the stack callers skipped amount. +func WrapSkip(skip int, err error, text string) error { + if err == nil { + return nil + } + return &Error{ + error: err, + stack: callers(skip), + text: text, + code: Code(err), + } +} + +// WrapSkipf wraps error with text that is formatted with given format and args. +// It returns nil if given err is nil. +// The parameter specifies the stack callers skipped amount. +func WrapSkipf(skip int, err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + return &Error{ + error: err, + stack: callers(skip), + text: fmt.Sprintf(format, args...), + code: Code(err), } } @@ -177,6 +207,36 @@ func WrapCodef(code int, err error, format string, args ...interface{}) error { } } +// WrapCodeSkip wraps error with code and text. +// It returns nil if given err is nil. +// The parameter specifies the stack callers skipped amount. +func WrapCodeSkip(code, skip int, err error, text string) error { + if err == nil { + return nil + } + return &Error{ + error: err, + stack: callers(skip), + text: text, + code: code, + } +} + +// WrapCodeSkipf wraps error with code and text that is formatted with given format and args. +// It returns nil if given err is nil. +// The parameter specifies the stack callers skipped amount. +func WrapCodeSkipf(code, skip int, err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + return &Error{ + error: err, + stack: callers(skip), + text: fmt.Sprintf(format, args...), + code: code, + } +} + // Cause returns the error code of current error. // It returns -1 if it has no error code or it does not implements interface Code. func Code(err error) int { diff --git a/errors/gerror/gerror_z_unit_test.go b/errors/gerror/gerror_z_unit_test.go index c7c6e2541..254f5c159 100644 --- a/errors/gerror/gerror_z_unit_test.go +++ b/errors/gerror/gerror_z_unit_test.go @@ -1,4 +1,4 @@ -// Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -26,6 +26,29 @@ func Test_Nil(t *testing.T) { }) } +func Test_New(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.Newf("%d", 1) + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.NewSkip(1, "1") + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.NewSkipf(1, "%d", 1) + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) +} + func Test_Wrap(t *testing.T) { gtest.C(t, func(t *gtest.T) { err := errors.New("1") @@ -49,6 +72,75 @@ func Test_Wrap(t *testing.T) { }) } +func Test_Wrapf(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + err := errors.New("1") + err = gerror.Wrapf(err, "%d", 2) + err = gerror.Wrapf(err, "%d", 3) + t.AssertNE(err, nil) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + err = gerror.Wrapf(err, "%d", 2) + err = gerror.Wrapf(err, "%d", 3) + t.AssertNE(err, nil) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + err = gerror.Wrapf(err, "") + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) +} + +func Test_WrapSkip(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + err := errors.New("1") + err = gerror.WrapSkip(1, err, "2") + err = gerror.WrapSkip(1, err, "3") + t.AssertNE(err, nil) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + err = gerror.WrapSkip(1, err, "2") + err = gerror.WrapSkip(1, err, "3") + t.AssertNE(err, nil) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + err = gerror.WrapSkip(1, err, "") + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) +} + +func Test_WrapSkipf(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + err := errors.New("1") + err = gerror.WrapSkipf(1, err, "2") + err = gerror.WrapSkipf(1, err, "3") + t.AssertNE(err, nil) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + err = gerror.WrapSkipf(1, err, "2") + err = gerror.WrapSkipf(1, err, "3") + t.AssertNE(err, nil) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := gerror.New("1") + err = gerror.WrapSkipf(1, err, "") + t.AssertNE(err, nil) + t.Assert(err.Error(), "1") + }) +} + func Test_Cause(t *testing.T) { gtest.C(t, func(t *gtest.T) { err := errors.New("1") @@ -201,4 +293,18 @@ func Test_Code(t *testing.T) { t.Assert(gerror.Code(err), 1) t.Assert(err.Error(), "3: 2: 1") }) + gtest.C(t, func(t *gtest.T) { + err := errors.New("1") + err = gerror.Wrap(err, "2") + err = gerror.WrapCodeSkip(1, 100, err, "3") + t.Assert(gerror.Code(err), 1) + t.Assert(err.Error(), "3: 2: 1") + }) + gtest.C(t, func(t *gtest.T) { + err := errors.New("1") + err = gerror.Wrap(err, "2") + err = gerror.WrapCodeSkipf(1, 100, err, "%s", "3") + t.Assert(gerror.Code(err), 1) + t.Assert(err.Error(), "3: 2: 1") + }) } diff --git a/net/ghttp/ghttp_func.go b/net/ghttp/ghttp_func.go index 8e6b06acd..3a03bdfea 100644 --- a/net/ghttp/ghttp_func.go +++ b/net/ghttp/ghttp_func.go @@ -1,4 +1,4 @@ -// Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -69,19 +69,23 @@ func BuildParams(params interface{}, noUrlEncode ...bool) (encodedParamStr strin // niceCallFunc calls function with exception capture logic. func niceCallFunc(f func()) { defer func() { - if e := recover(); e != nil { - switch e { + if exception := recover(); exception != nil { + switch exception { case exceptionExit, exceptionExitAll: return default: - if _, ok := e.(errorStack); ok { + if _, ok := exception.(errorStack); ok { // It's already an error that has stack info. - panic(e) + panic(exception) } else { // Create a new error with stack info. // Note that there's a skip pointing the start stacktrace // of the real error point. - panic(gerror.NewSkipf(1, "%v", e)) + if err, ok := exception.(error); ok { + panic(gerror.Wrap(err, "")) + } else { + panic(gerror.NewSkipf(1, "%v", exception)) + } } } } diff --git a/net/ghttp/ghttp_request_middleware.go b/net/ghttp/ghttp_request_middleware.go index 13da4129d..6ddcde54e 100644 --- a/net/ghttp/ghttp_request_middleware.go +++ b/net/ghttp/ghttp_request_middleware.go @@ -1,4 +1,4 @@ -// Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -128,7 +128,7 @@ func (m *Middleware) Next() { // Create a new error with stack info. // Note that there's a skip pointing the start stacktrace // of the real error point. - m.request.error = gerror.NewSkip(1, exception.Error()) + m.request.error = gerror.WrapSkip(1, exception, "") } m.request.Response.WriteStatus(http.StatusInternalServerError, exception) loop = false diff --git a/net/ghttp/ghttp_server_handler.go b/net/ghttp/ghttp_server_handler.go index fbe416a8b..8c7e24854 100644 --- a/net/ghttp/ghttp_server_handler.go +++ b/net/ghttp/ghttp_server_handler.go @@ -1,4 +1,4 @@ -// Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, @@ -65,7 +65,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } else { if exception := recover(); exception != nil { request.Response.WriteStatus(http.StatusInternalServerError) - s.handleErrorLog(gerror.Newf("%v", exception), request) + if err, ok := exception.(error); ok { + s.handleErrorLog(gerror.Wrap(err, ""), request) + } else { + s.handleErrorLog(gerror.Newf("%v", exception), request) + } } } // access log handling. diff --git a/net/ghttp/ghttp_server_log.go b/net/ghttp/ghttp_server_log.go index 93e66dcb5..c8f0f5f8f 100644 --- a/net/ghttp/ghttp_server_log.go +++ b/net/ghttp/ghttp_server_log.go @@ -1,4 +1,4 @@ -// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file,