Skip to content

Commit

Permalink
Merge pull request #7 from axone-protocol/feat/impove-panic-error
Browse files Browse the repository at this point in the history
Wrap panic errors
  • Loading branch information
bdeneux authored Jul 24, 2024
2 parents b5a8728 + 7d0eab8 commit ea00e9b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 5 deletions.
8 changes: 6 additions & 2 deletions engine/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func TestCall(t *testing.T) {
panic("told you")
})
})
vm.Register0(NewAtom("do_not_call_wrapped"), func(*VM, Cont, *Env) *Promise {
panic(errors.New("told you"))
})
assert.NoError(t, vm.Compile(context.Background(), `
foo.
foo(_, _).
Expand Down Expand Up @@ -60,8 +63,9 @@ f(g([a, [b, c|X]])).

{title: `cover all`, goal: atomComma.Apply(atomCut, NewAtom("f").Apply(NewAtom("g").Apply(List(NewAtom("a"), PartialList(NewVariable(), NewAtom("b"), NewAtom("c")))))), ok: true},
{title: `out of memory`, goal: NewAtom("foo").Apply(NewVariable(), NewVariable(), NewVariable(), NewVariable(), NewVariable(), NewVariable(), NewVariable(), NewVariable(), NewVariable()), err: resourceError(resourceMemory, nil), mem: 1},
{title: `panic`, goal: NewAtom("do_not_call"), err: errors.New("panic: told you")},
{title: `panic (lazy)`, goal: NewAtom("lazy_do_not_call"), err: errors.New("panic: told you")},
{title: `panic`, goal: NewAtom("do_not_call"), err: PanicError{errors.New("told you")}},
{title: `panic (lazy)`, goal: NewAtom("lazy_do_not_call"), err: PanicError{errors.New("told you")}},
{title: `panic (wrapped)`, goal: NewAtom("do_not_call_wrapped"), err: PanicError{errors.New("told you")}},
}

for _, tt := range tests {
Expand Down
16 changes: 15 additions & 1 deletion engine/promise.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,12 @@ func ensurePromise(p **Promise) {
}

func panicError(r interface{}) error {
return fmt.Errorf("panic: %v", r)
switch r := r.(type) {
case error:
return PanicError{r}
default:
return PanicError{fmt.Errorf("%v", r)}
}
}

type promiseStack []*Promise
Expand Down Expand Up @@ -164,3 +169,12 @@ func (s *promiseStack) recover(err error) error {
// went through all the ancestor promises and still got the unhandled error.
return err
}

// PanicError is an error thrown once panic occurs during the execution of a promise.
type PanicError struct {
OriginErr error
}

func (p PanicError) Error() string {
return fmt.Sprintf("panic: %v", p.OriginErr)
}
4 changes: 2 additions & 2 deletions engine/variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"sync"
)

var errMaxVariables = errors.New("maximum number of variables reached")
var ErrMaxVariables = errors.New("maximum number of variables reached")

var maxVariables uint64
var varCounter = struct {
Expand All @@ -31,7 +31,7 @@ func NewVariable() Variable {
defer varCounter.Unlock()
varCounter.Lock()
if maxVariables != 0 && varCounter.count >= maxVariables {
panic(errMaxVariables)
panic(ErrMaxVariables)
}
varCounter.count++
return Variable(varCounter.count)
Expand Down

0 comments on commit ea00e9b

Please sign in to comment.