From b42132a7a37d27d8cee21c02d56243b6bcf5e3fb Mon Sep 17 00:00:00 2001 From: Rudo Thomas Date: Thu, 30 Jun 2022 11:17:26 +0200 Subject: [PATCH] feat: Report native function panics as runtime errors. Previously, you'd get an "INTERNAL ERROR: (CRASH)" with a full backtrace and a link to file a bug against go-jsonnet. --- main_test.go | 9 +++++++++ testdata/native_panic.golden | 10 ++++++++++ testdata/native_panic.jsonnet | 1 + testdata/native_panic.linter.golden | 0 thunks.go | 11 ++++++++++- 5 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 testdata/native_panic.golden create mode 100644 testdata/native_panic.jsonnet create mode 100644 testdata/native_panic.linter.golden diff --git a/main_test.go b/main_test.go index 9e230a5..85aa981 100644 --- a/main_test.go +++ b/main_test.go @@ -96,6 +96,14 @@ var nativeError = &NativeFunction{ }, } +var nativePanic = &NativeFunction{ + Name: "nativePanic", + Params: ast.Identifiers{}, + Func: func(x []interface{}) (interface{}, error) { + panic("native function panic") + }, +} + type jsonnetInput struct { name string input []byte @@ -136,6 +144,7 @@ func runInternalJsonnet(i jsonnetInput) jsonnetResult { vm.NativeFunction(jsonToString) vm.NativeFunction(nativeError) + vm.NativeFunction(nativePanic) rawAST, _, staticErr := parser.SnippetToRawAST(ast.DiagnosticFileName(i.name), "", string(i.input)) if staticErr != nil { diff --git a/testdata/native_panic.golden b/testdata/native_panic.golden new file mode 100644 index 0000000..9f261d2 --- /dev/null +++ b/testdata/native_panic.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: native function "nativePanic" panicked: native function panic +------------------------------------------------- + testdata/native_panic:1:1-28 $ + +std.native("nativePanic")() + +------------------------------------------------- + During evaluation + + diff --git a/testdata/native_panic.jsonnet b/testdata/native_panic.jsonnet new file mode 100644 index 0000000..2698c84 --- /dev/null +++ b/testdata/native_panic.jsonnet @@ -0,0 +1 @@ +std.native("nativePanic")() diff --git a/testdata/native_panic.linter.golden b/testdata/native_panic.linter.golden new file mode 100644 index 0000000..e69de29 diff --git a/thunks.go b/thunks.go index d332d51..c1880e7 100644 --- a/thunks.go +++ b/thunks.go @@ -17,6 +17,7 @@ limitations under the License. package jsonnet import ( + "fmt" "github.com/google/go-jsonnet/ast" ) @@ -273,7 +274,15 @@ func (native *NativeFunction) evalCall(arguments callArguments, i *interpreter) } nativeArgs = append(nativeArgs, json) } - resultJSON, err := native.Func(nativeArgs) + call := func() (resultJSON interface{}, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("native function %#v panicked: %v", native.Name, r) + } + }() + return native.Func(nativeArgs) + } + resultJSON, err := call() if err != nil { return nil, i.Error(err.Error()) }