add function gutil.Try/g.Try;improve error string for gconv.Struct

This commit is contained in:
Jack
2020-10-20 13:36:43 +08:00
parent 0a203d1e22
commit 77f7884604
8 changed files with 52 additions and 16 deletions

View File

@ -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()

View File

@ -11,7 +11,7 @@ func main() {
fmt.Println(1)
gutil.Throw("error")
fmt.Println(2)
}, func(err interface{}) {
}, func(err error) {
fmt.Println(err)
})
}

View File

@ -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 <catch> if any exception occurs ans passes the exception as an error.
func TryCatch(try func(), catch ...func(exception error)) {
gutil.TryCatch(try, catch...)
}

View File

@ -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)

View File

@ -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
}
}

View File

@ -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 <catch> 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()

View File

@ -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) {
})
}

View File

@ -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")