From e10a35d3dffdbd6ec83ca65b2f76d6a12ab373b8 Mon Sep 17 00:00:00 2001 From: hesining <37295940+hesining@users.noreply.github.com> Date: Sat, 11 Mar 2023 04:08:40 +0800 Subject: [PATCH] Add Wrap and Unwrap method to hold self error (#352) --- expr_test.go | 2 +- file/error.go | 11 +++++++++++ vm/vm.go | 3 +++ vm/vm_test.go | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/expr_test.go b/expr_test.go index 0549dfe72..cfe594a71 100644 --- a/expr_test.go +++ b/expr_test.go @@ -1348,7 +1348,7 @@ func TestCompile_exposed_error(t *testing.T) { b, err := json.Marshal(err) require.NoError(t, err) - require.Equal(t, `{"Line":1,"Column":2,"Message":"invalid operation: == (mismatched types int and bool)","Snippet":"\n | 1 == true\n | ..^"}`, string(b)) + require.Equal(t, `{"Line":1,"Column":2,"Message":"invalid operation: == (mismatched types int and bool)","Snippet":"\n | 1 == true\n | ..^","Prev":null}`, string(b)) } func TestCompile_deref(t *testing.T) { diff --git a/file/error.go b/file/error.go index b7af3e6e2..1e7e81b94 100644 --- a/file/error.go +++ b/file/error.go @@ -10,6 +10,7 @@ type Error struct { Location Message string Snippet string + Prev error } func (e *Error) Error() string { @@ -44,6 +45,16 @@ func (e *Error) Bind(source *Source) *Error { return e } + +func (e *Error) Unwrap() error { + return e.Prev +} + +func (e *Error) Wrap(err error) { + e.Prev = err +} + + func (e *Error) format() string { if e.Location.Empty() { return e.Message diff --git a/vm/vm.go b/vm/vm.go index 46f7628f2..af4fc5bf7 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -61,6 +61,9 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error) Location: program.Locations[vm.ip-1], Message: fmt.Sprintf("%v", r), } + if err, ok := r.(error); ok { + f.Wrap(err) + } err = f.Bind(program.Source) } }() diff --git a/vm/vm_test.go b/vm/vm_test.go index 0fc291bc2..6e32d4713 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -274,6 +274,10 @@ func TestRun_MethodWithError(t *testing.T) { out, err := vm.Run(program, env) require.EqualError(t, err, "error (1:1)\n | WillError(\"yes\")\n | ^") require.Equal(t, nil, out) + + selfErr := errors.Unwrap(err) + require.NotNil(t, err) + require.Equal(t, "error", selfErr.Error()) } func TestRun_FastMethods(t *testing.T) {