]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: emit field error over nil pointer error where appropriate
authorAndrew Gerrand <adg@golang.org>
Fri, 8 Apr 2016 05:39:32 +0000 (15:39 +1000)
committerAndrew Gerrand <adg@golang.org>
Sun, 10 Apr 2016 23:29:29 +0000 (23:29 +0000)
When evaluating "{{.MissingField}}" on a nil *T, Exec returns
"can't evaluate field MissingField in type *T" instead of
"nil pointer evaluating *T.MissingField".

Fixes golang/go#15125

Change-Id: I6e73f61b8a72c694179c1f8cdc808766c90b6f57
Reviewed-on: https://go-review.googlesource.com/21705
Reviewed-by: Rob Pike <r@golang.org>
src/text/template/exec.go
src/text/template/exec_test.go

index a169e62ab018e4f155d4e5e1aae4665ecd5ac1b1..22881c685279f6a94561e6c69867aedbe151f52e 100644 (file)
@@ -538,14 +538,14 @@ func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node,
                return s.evalCall(dot, method, node, fieldName, args, final)
        }
        hasArgs := len(args) > 1 || final.IsValid()
-       // It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil.
-       if isNil {
-               s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
-       }
+       // It's not a method; must be a field of a struct or an element of a map.
        switch receiver.Kind() {
        case reflect.Struct:
                tField, ok := receiver.Type().FieldByName(fieldName)
                if ok {
+                       if isNil {
+                               s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
+                       }
                        field := receiver.FieldByIndex(tField.Index)
                        if tField.PkgPath != "" { // field is unexported
                                s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
@@ -556,8 +556,10 @@ func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node,
                        }
                        return field
                }
-               s.errorf("%s is not a field of struct type %s", fieldName, typ)
        case reflect.Map:
+               if isNil {
+                       s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
+               }
                // If it's a map, attempt to use the field name as a key.
                nameVal := reflect.ValueOf(fieldName)
                if nameVal.Type().AssignableTo(receiver.Type().Key()) {
index e507e917fe51aa48b4e785b01aef3815b71aaf8f..bc2aa683ec9a0695f0f995e3a2a40545305f7b78 100644 (file)
@@ -1280,3 +1280,20 @@ func TestBlock(t *testing.T) {
                t.Errorf("got %q, want %q", got, want2)
        }
 }
+
+// Check that calling an invalid field on nil pointer prints
+// a field error instead of a distracting nil pointer error.
+// https://golang.org/issue/15125
+func TestMissingFieldOnNil(t *testing.T) {
+       tmpl := Must(New("tmpl").Parse("{{.MissingField}}"))
+       var d *T
+       err := tmpl.Execute(ioutil.Discard, d)
+       got := "<nil>"
+       if err != nil {
+               got = err.Error()
+       }
+       want := "can't evaluate field MissingField in type *template.T"
+       if !strings.HasSuffix(got, want) {
+               t.Errorf("got error %q, want %q", got, want)
+       }
+}