mirror of
https://github.com/kataras/iris.git
synced 2025-03-21 11:16:28 +01:00
add support for mvc and hero dynamic dependencies to understand the error type as a second output value as requested at: https://github.com/kataras/iris/issues/1187
Former-commit-id: 49e29c06aaaa22743354981342c29fc9d5953d0e
This commit is contained in:
parent
07994adabb
commit
9cfaff07d6
|
@ -77,8 +77,10 @@ func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker) (func([]reflect.Val
|
||||||
return nil, typ, errBad
|
return nil, typ, errBad
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalid if not returns one single value.
|
n := typ.NumOut()
|
||||||
if typ.NumOut() != 1 {
|
|
||||||
|
// invalid if not returns one single value or two values but the second is not an error.
|
||||||
|
if !(n == 1 || (n == 2 && IsError(typ.Out(1)))) {
|
||||||
return nil, typ, errBad
|
return nil, typ, errBad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,19 +90,36 @@ func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker) (func([]reflect.Val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outTyp := typ.Out(0)
|
firstOutTyp := typ.Out(0)
|
||||||
zeroOutVal := reflect.New(outTyp).Elem()
|
firstZeroOutVal := reflect.New(firstOutTyp).Elem()
|
||||||
|
|
||||||
bf := func(ctxValue []reflect.Value) reflect.Value {
|
bf := func(ctxValue []reflect.Value) reflect.Value {
|
||||||
results := fn.Call(ctxValue)
|
results := fn.Call(ctxValue)
|
||||||
if len(results) == 0 {
|
|
||||||
return zeroOutVal
|
|
||||||
}
|
|
||||||
|
|
||||||
v := results[0]
|
v := results[0]
|
||||||
if !v.IsValid() {
|
if !v.IsValid() { // check the first value, second is error.
|
||||||
return zeroOutVal
|
return firstZeroOutVal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n == 2 {
|
||||||
|
// two, second is always error.
|
||||||
|
errVal := results[1]
|
||||||
|
if !errVal.IsNil() {
|
||||||
|
// error is not nil, do something with it.
|
||||||
|
if ctx, ok := ctxValue[0].Interface().(interface {
|
||||||
|
StatusCode(int)
|
||||||
|
WriteString(string) (int, error)
|
||||||
|
StopExecution()
|
||||||
|
}); ok {
|
||||||
|
ctx.StatusCode(400)
|
||||||
|
ctx.WriteString(errVal.Interface().(error).Error())
|
||||||
|
ctx.StopExecution()
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstZeroOutVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if v.String() == "<interface {} Value>" {
|
// if v.String() == "<interface {} Value>" {
|
||||||
// println("di/object.go: " + v.String())
|
// println("di/object.go: " + v.String())
|
||||||
// // println("di/object.go: because it's interface{} it should be returned as: " + v.Elem().Type().String() + " and its value: " + v.Elem().Interface().(string))
|
// // println("di/object.go: because it's interface{} it should be returned as: " + v.Elem().Type().String() + " and its value: " + v.Elem().Interface().(string))
|
||||||
|
@ -109,7 +128,7 @@ func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker) (func([]reflect.Val
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
return bf, outTyp, nil
|
return bf, firstOutTyp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAssignable checks if "to" type can be used as "b.Value/ReturnValue".
|
// IsAssignable checks if "to" type can be used as "b.Value/ReturnValue".
|
||||||
|
|
|
@ -59,6 +59,13 @@ func IsZero(v reflect.Value) bool {
|
||||||
return v.Interface() == zero.Interface()
|
return v.Interface() == zero.Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errTyp = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
|
|
||||||
|
// IsError returns true if "typ" is type of `error`.
|
||||||
|
func IsError(typ reflect.Type) bool {
|
||||||
|
return typ.Implements(errTyp)
|
||||||
|
}
|
||||||
|
|
||||||
// IndirectValue returns the reflect.Value that "v" points to.
|
// IndirectValue returns the reflect.Value that "v" points to.
|
||||||
// If "v" is a nil pointer, Indirect returns a zero Value.
|
// If "v" is a nil pointer, Indirect returns a zero Value.
|
||||||
// If "v" is not a pointer, Indirect returns v.
|
// If "v" is not a pointer, Indirect returns v.
|
||||||
|
|
|
@ -398,6 +398,10 @@ func (c *ControllerActivator) handlerOf(m reflect.Method, funcDependencies []ref
|
||||||
in[0] = ctrl
|
in[0] = ctrl
|
||||||
funcInjector.Inject(&in, ctxValue)
|
funcInjector.Inject(&in, ctxValue)
|
||||||
|
|
||||||
|
if ctx.IsStopped() {
|
||||||
|
return // stop as soon as possible, although it would stop later on if `ctx.StopExecution` called.
|
||||||
|
}
|
||||||
|
|
||||||
// for idxx, inn := range in {
|
// for idxx, inn := range in {
|
||||||
// println("controller.go: execution: in.Value = "+inn.String()+" and in.Type = "+inn.Type().Kind().String()+" of index: ", idxx)
|
// println("controller.go: execution: in.Value = "+inn.String()+" and in.Type = "+inn.Type().Kind().String()+" of index: ", idxx)
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -272,11 +272,22 @@ type testControllerBindDeep struct {
|
||||||
testControllerBindStruct
|
testControllerBindStruct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *testControllerBindDeep) BeforeActivation(b BeforeActivation) {
|
||||||
|
b.Dependencies().Add(func(ctx iris.Context) (v testCustomStruct, err error) {
|
||||||
|
err = ctx.ReadJSON(&v)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (t *testControllerBindDeep) Get() {
|
func (t *testControllerBindDeep) Get() {
|
||||||
// t.testControllerBindStruct.Get()
|
// t.testControllerBindStruct.Get()
|
||||||
t.Ctx.Writef(t.TitlePointer.title + t.TitleValue.title + t.Other)
|
t.Ctx.Writef(t.TitlePointer.title + t.TitleValue.title + t.Other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *testControllerBindDeep) Post(v testCustomStruct) string {
|
||||||
|
return v.Name
|
||||||
|
}
|
||||||
|
|
||||||
func TestControllerDependencies(t *testing.T) {
|
func TestControllerDependencies(t *testing.T) {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
// app.Logger().SetLevel("debug")
|
// app.Logger().SetLevel("debug")
|
||||||
|
@ -299,6 +310,12 @@ func TestControllerDependencies(t *testing.T) {
|
||||||
|
|
||||||
e.GET("/deep").Expect().Status(iris.StatusOK).
|
e.GET("/deep").Expect().Status(iris.StatusOK).
|
||||||
Body().Equal(expected)
|
Body().Equal(expected)
|
||||||
|
|
||||||
|
e.POST("/deep").WithJSON(iris.Map{"name": "kataras"}).Expect().Status(iris.StatusOK).
|
||||||
|
Body().Equal("kataras")
|
||||||
|
|
||||||
|
e.POST("/deep").Expect().Status(iris.StatusBadRequest).
|
||||||
|
Body().Equal("unexpected end of JSON input")
|
||||||
}
|
}
|
||||||
|
|
||||||
type testCtrl0 struct {
|
type testCtrl0 struct {
|
||||||
|
|
|
@ -808,7 +808,7 @@ func DialContext(ctx stdContext.Context, url string, cfg ConnectionConfig) (Clie
|
||||||
ctx = stdContext.Background()
|
ctx = stdContext.Background()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(url, "ws://") {
|
if !strings.HasPrefix(url, "ws://") || !strings.HasPrefix(url, "wss://") {
|
||||||
url = "ws://" + url
|
url = "ws://" + url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user