anindyaju99
anindyaju99

Reputation: 475

Reflection - method call panics with "call of reflect.Value.Elem on struct Value"

Here is a code snippet -

type Gateway struct {
    Svc1 svc1.Interface
    Svc2 svc2.Interface
}

func (g *Gateway) GetClient(service string) interface{} {
    ps := reflect.ValueOf(g)
    s := ps.Elem()
    f := s.FieldByName(strings.Title(service))
    return f.Interface()
}

func (g *Gateway) Invoke(service string, endpoint string, args... 
    interface{}) []reflect.Value {
    log.Info("Gateway.Invoke " + service + "." + endpoint)
    inputs := make([]reflect.Value, len(args))
    for i, _ := range args {
        inputs[i] = reflect.ValueOf(args[i])
    }

    client := g.GetClient(service)

    return reflect.ValueOf(client).Elem().MethodByName(endpoint).Call(inputs)
}

GetClient("svc1") works fine.

However, when I call Invoke("svc1", "endpoint1", someArg), it panics saying -

reflect: call of reflect.Value.Elem on struct Value

reflect.ValueOf(client).MethodByName(endpoint).Call(inputs) panics saying Call on a zero value.

Upvotes: 8

Views: 44600

Answers (1)

Federico
Federico

Reputation: 166

There are a couple issues:

  1. If svc1.Interface is not a pointer or an interface, reflect.Value.Elem() will panic (see https://golang.org/pkg/reflect/#Value.Elem)

  2. If the endpoint argument string of Invoke doesn't match the capitalization of the target method, it will panic due to zero value (invalid reflect.Value). Please note that the method you want to call must be exported.

Upvotes: 12

Related Questions