diff --git a/.example/net/ghttp/server/hello.go b/.example/net/ghttp/server/hello.go index 5cdadabc1..12afb54da 100644 --- a/.example/net/ghttp/server/hello.go +++ b/.example/net/ghttp/server/hello.go @@ -3,15 +3,21 @@ package main import ( "github.com/gogf/gf/frame/g" "github.com/gogf/gf/net/ghttp" - "github.com/gogf/gf/os/glog" ) +type GetById struct { + Id *g.Var `p:"id" v:"required|integer#id不能为空|id必须为整数"` +} + func main() { s := g.Server() s.SetIndexFolder(true) s.BindHandler("/", func(r *ghttp.Request) { - glog.Println(r.Header) - r.Response.Write("hello world") + var idInfo *GetById + if err := r.Parse(&idInfo); err != nil { + r.Response.Write(err) + } + r.Response.Write("ok") }) s.SetPort(8999) s.Run() diff --git a/.example/util/gutil/try_catch.go b/.example/util/gutil/try_catch.go index 6ae1afea4..0aa3ccf4b 100644 --- a/.example/util/gutil/try_catch.go +++ b/.example/util/gutil/try_catch.go @@ -11,7 +11,7 @@ func main() { fmt.Println(1) gutil.Throw("error") fmt.Println(2) - }, func(err interface{}) { + }, func(err error) { fmt.Println(err) }) } diff --git a/frame/g/g_func.go b/frame/g/g_func.go index 923eb7749..d99a77ff3 100644 --- a/frame/g/g_func.go +++ b/frame/g/g_func.go @@ -39,8 +39,15 @@ func Throw(exception interface{}) { gutil.Throw(exception) } -// TryCatch does the try...catch... mechanism. -func TryCatch(try func(), catch ...func(exception interface{})) { +// Try implements try... logistics using internal panic...recover. +// It returns error if any exception occurs, or else it returns nil. +func Try(try func()) (err error) { + return gutil.Try(try) +} + +// TryCatch implements try...catch... logistics using internal panic...recover. +// It automatically calls function if any exception occurs ans passes the exception as an error. +func TryCatch(try func(), catch ...func(exception error)) { gutil.TryCatch(try, catch...) } diff --git a/net/ghttp/ghttp_request_middleware.go b/net/ghttp/ghttp_request_middleware.go index 813836cc4..4b46904bc 100644 --- a/net/ghttp/ghttp_request_middleware.go +++ b/net/ghttp/ghttp_request_middleware.go @@ -120,7 +120,7 @@ func (m *Middleware) Next() { // There should be a "Next" function to be called in the middleware in order to manage the workflow. loop = false } - }, func(exception interface{}) { + }, func(exception error) { if e, ok := exception.(gerror.ApiStack); ok { // It's already an error that has stack info. m.request.error = e.(error) diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index cf31d8634..f01d4c759 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -259,8 +259,11 @@ func bindVarToStructAttr(elem reflect.Value, name string, value interface{}, rec return nil } defer func() { - if recover() != nil { + if e := recover(); e != nil { err = bindVarToReflectValue(structFieldValue, value, recursive, mapping...) + if err != nil { + err = gerror.Wrapf(err, `error binding value to attribute "%s"`, name) + } } }() if empty.IsNil(value) { @@ -283,8 +286,7 @@ func bindVarToReflectValue(structFieldValue reflect.Value, value interface{}, re v.Set(value) return nil } else if v, ok := structFieldValue.Interface().(apiUnmarshalValue); ok { - err = v.UnmarshalValue(value) - if err == nil { + if err = v.UnmarshalValue(value); err == nil { return err } } diff --git a/util/gutil/gutil.go b/util/gutil/gutil.go index f3942747e..35fb1d1db 100644 --- a/util/gutil/gutil.go +++ b/util/gutil/gutil.go @@ -8,6 +8,7 @@ package gutil import ( + "fmt" "github.com/gogf/gf/internal/empty" ) @@ -16,11 +17,24 @@ func Throw(exception interface{}) { panic(exception) } +// Try implements try... logistics using internal panic...recover. +// It returns error if any exception occurs, or else it returns nil. +func Try(try func()) (err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf(`%v`, e) + } + }() + try() + return +} + // TryCatch implements try...catch... logistics using internal panic...recover. -func TryCatch(try func(), catch ...func(exception interface{})) { +// It automatically calls function if any exception occurs ans passes the exception as an error. +func TryCatch(try func(), catch ...func(exception error)) { defer func() { if e := recover(); e != nil && len(catch) > 0 { - catch[0](e) + catch[0](fmt.Errorf(`%v`, e)) } }() try() diff --git a/util/gutil/gutil_z_bench_test.go b/util/gutil/gutil_z_bench_test.go index 2276c021f..f08e48015 100644 --- a/util/gutil/gutil_z_bench_test.go +++ b/util/gutil/gutil_z_bench_test.go @@ -25,7 +25,7 @@ func Benchmark_TryCatch(b *testing.B) { for i := 0; i < b.N; i++ { TryCatch(func() { - }, func(err interface{}) { + }, func(err error) { }) } diff --git a/util/gutil/gutil_z_unit_test.go b/util/gutil/gutil_z_unit_test.go index dbd6d0469..87979b8ab 100755 --- a/util/gutil/gutil_z_unit_test.go +++ b/util/gutil/gutil_z_unit_test.go @@ -21,6 +21,15 @@ func Test_Dump(t *testing.T) { }) } +func Test_Try(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + s := `gutil Try test` + t.Assert(gutil.Try(func() { + panic(s) + }), s) + }) +} + func Test_TryCatch(t *testing.T) { gtest.C(t, func(t *gtest.T) { gutil.TryCatch(func() { @@ -32,21 +41,19 @@ func Test_TryCatch(t *testing.T) { gutil.TryCatch(func() { panic("gutil TryCatch test") - }, func(err interface{}) { + }, func(err error) { t.Assert(err, "gutil TryCatch test") }) }) } func Test_IsEmpty(t *testing.T) { - gtest.C(t, func(t *gtest.T) { t.Assert(gutil.IsEmpty(1), false) }) } func Test_Throw(t *testing.T) { - gtest.C(t, func(t *gtest.T) { defer func() { t.Assert(recover(), "gutil Throw test")