mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
improve error reporting for bad templates
This commit is contained in:
parent
6916235513
commit
16c624b2e6
@ -327,7 +327,8 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
||||
|
||||
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
||||
type TemplatePrinter struct {
|
||||
template *template.Template
|
||||
rawTemplate string
|
||||
template *template.Template
|
||||
}
|
||||
|
||||
func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
||||
@ -335,17 +336,27 @@ func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &TemplatePrinter{t}, nil
|
||||
return &TemplatePrinter{string(tmpl), t}, nil
|
||||
}
|
||||
|
||||
// Print parses the data as JSON, and re-formats it with the Go Template.
|
||||
func (t *TemplatePrinter) Print(data []byte, w io.Writer) error {
|
||||
obj := map[string]interface{}{}
|
||||
err := json.Unmarshal(data, &obj)
|
||||
out := map[string]interface{}{}
|
||||
err := json.Unmarshal(data, &out)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.template.Execute(w, obj)
|
||||
if err := t.template.Execute(w, out); err != nil {
|
||||
// It is way easier to debug this stuff when it shows up in
|
||||
// stdout instead of just stdin. So in addition to returning
|
||||
// a nice error, also print useful stuff with the writer.
|
||||
fmt.Fprintf(w, "Error executing template: %v\n", err)
|
||||
fmt.Fprintf(w, "template was:\n%v\n", t.rawTemplate)
|
||||
fmt.Fprintf(w, "raw data was:\n%v\n", string(data))
|
||||
fmt.Fprintf(w, "object given to template engine was:\n%+v\n", out)
|
||||
return fmt.Errorf("error executing template '%v': '%v'\n----data----\n%#v\n", t.rawTemplate, err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintObj formats the obj with the Go Template.
|
||||
|
@ -177,3 +177,20 @@ func TestTemplateEmitsVersionedObjects(t *testing.T) {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplatePanic(t *testing.T) {
|
||||
tmpl := `{{and ((index .currentState.info "update-demo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}`
|
||||
// kind is always blank in memory and set on the wire
|
||||
printer, err := NewTemplatePrinter([]byte(tmpl))
|
||||
if err != nil {
|
||||
t.Fatalf("tmpl fail: %v", err)
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
err = printer.PrintObj(&api.Pod{}, buffer)
|
||||
if err == nil {
|
||||
t.Fatalf("expected that template to crash")
|
||||
}
|
||||
if buffer.String() == "" {
|
||||
t.Errorf("no debugging info was printed")
|
||||
}
|
||||
}
|
||||
|
@ -417,7 +417,14 @@ func (p *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
if err = p.template.Execute(w, out); err != nil {
|
||||
return fmt.Errorf("error executing template '%v': '%v'\n----data----\n%#v\n", p.rawTemplate, err, out)
|
||||
// It is way easier to debug this stuff when it shows up in
|
||||
// stdout instead of just stdin. So in addition to returning
|
||||
// a nice error, also print useful stuff with the writer.
|
||||
fmt.Fprintf(w, "Error executing template: %v\n", err)
|
||||
fmt.Fprintf(w, "template was:\n\t%v\n", p.rawTemplate)
|
||||
fmt.Fprintf(w, "raw data was:\n\t%v\n", string(data))
|
||||
fmt.Fprintf(w, "object given to template engine was:\n\t%+v\n", out)
|
||||
return fmt.Errorf("error executing template '%v': '%v'\n----data----\n%+v\n", p.rawTemplate, err, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -290,6 +290,23 @@ func TestTemplateEmitsVersionedObjects(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplatePanic(t *testing.T) {
|
||||
tmpl := `{{and ((index .currentState.info "update-demo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}`
|
||||
// kind is always blank in memory and set on the wire
|
||||
printer, err := NewTemplatePrinter([]byte(tmpl), testapi.Version(), api.Scheme)
|
||||
if err != nil {
|
||||
t.Fatalf("tmpl fail: %v", err)
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
err = printer.PrintObj(&api.Pod{}, buffer)
|
||||
if err == nil {
|
||||
t.Fatalf("expected that template to crash")
|
||||
}
|
||||
if buffer.String() == "" {
|
||||
t.Errorf("no debugging info was printed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrinters(t *testing.T) {
|
||||
om := func(name string) api.ObjectMeta { return api.ObjectMeta{Name: name} }
|
||||
templatePrinter, err := NewTemplatePrinter([]byte("{{.name}}"), testapi.Version(), api.Scheme)
|
||||
|
Loading…
Reference in New Issue
Block a user