From 04bca414ad2b66fd0ad1a2c809cf7888e48f230d Mon Sep 17 00:00:00 2001 From: Aliipou Date: Fri, 20 Mar 2026 23:47:35 +0200 Subject: [PATCH] fix: align toToml error behavior with toYaml and toJson (closes #31430) toToml was returning err.Error() on marshal failure, while toYaml and toJson return an empty string. This caused confusing template output when marshaling fails (e.g. a struct with cyclic references). Changes: - toTOML now returns "" on error, consistent with toYAML and toJSON - Added mustToTOML which panics on error, consistent with mustToYAML and mustToJSON (allows templates to opt-in to strict error handling) - Registered mustToToml in funcMap - Added test cases for toToml error swallowing and mustToToml panic Signed-off-by: Aliipou --- pkg/engine/engine_test.go | 2 +- pkg/engine/funcs.go | 19 ++++++++++++++++++- pkg/engine/funcs_test.go | 7 +++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 09edc3337..0e5c66431 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -83,7 +83,7 @@ func TestFuncMap(t *testing.T) { } // Test for Engine-specific template functions. - expect := []string{"include", "required", "tpl", "toYaml", "fromYaml", "toToml", "fromToml", "toJson", "fromJson", "lookup"} + expect := []string{"include", "required", "tpl", "toYaml", "fromYaml", "toToml", "mustToToml", "fromToml", "toJson", "fromJson", "lookup"} for _, f := range expect { if _, ok := fns[f]; !ok { t.Errorf("Expected add-on function %q", f) diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index ba842a51a..0615284e9 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -50,6 +50,7 @@ func funcMap() template.FuncMap { // Add some extra functionality extra := template.FuncMap{ "toToml": toTOML, + "mustToToml": mustToTOML, "fromToml": fromTOML, "toYaml": toYAML, "mustToYaml": mustToYAML, @@ -157,7 +158,23 @@ func toTOML(v any) string { e := toml.NewEncoder(b) err := e.Encode(v) if err != nil { - return err.Error() + // Swallow errors inside of a template. + return "" + } + return b.String() +} + +// mustToTOML takes an interface, marshals it to toml, and returns a string. +// It will panic if there is an error. +// +// This is designed to be called from a template when need to ensure that the +// output TOML is valid. +func mustToTOML(v any) string { + b := bytes.NewBuffer(nil) + e := toml.NewEncoder(b) + err := e.Encode(v) + if err != nil { + panic(err) } return b.String() } diff --git a/pkg/engine/funcs_test.go b/pkg/engine/funcs_test.go index 48202454e..855090010 100644 --- a/pkg/engine/funcs_test.go +++ b/pkg/engine/funcs_test.go @@ -151,6 +151,9 @@ keyInElement1 = "valueInElement1"`, }, { tpl: `{{ mustToJson . }}`, vars: loopMap, + }, { + tpl: `{{ mustToToml . }}`, + vars: loopMap, }, { tpl: `{{ toYaml . }}`, expect: "", // should return empty string and swallow error @@ -159,6 +162,10 @@ keyInElement1 = "valueInElement1"`, tpl: `{{ toJson . }}`, expect: "", // should return empty string and swallow error vars: loopMap, + }, { + tpl: `{{ toToml . }}`, + expect: "", // should return empty string and swallow error + vars: loopMap, }, }