1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-14 11:23:02 +02:00

Added panic recovery mechanism (#158)

This commit is contained in:
Tim Voronov 2018-11-05 11:45:33 -05:00 committed by GitHub
parent 4032e8dd7c
commit 5e6701f1c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 4 deletions

View File

@ -59,9 +59,6 @@ func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error
return nil, ErrEmptyQuery
}
p := parser.New(query)
p.AddErrorListener(&errorListener{})
defer func() {
if r := recover(); r != nil {
// find out exactly what the error was and set err
@ -78,6 +75,9 @@ func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error
}
}()
p := parser.New(query)
p.AddErrorListener(&errorListener{})
l := newVisitor(query, c.funcs)
res := p.Visit(l).(*result)

View File

@ -5,6 +5,7 @@ import (
"github.com/MontFerret/ferret/pkg/html"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/pkg/errors"
)
type Program struct {
@ -28,7 +29,23 @@ func (p *Program) Source() string {
return p.src
}
func (p *Program) Run(ctx context.Context, setters ...Option) ([]byte, error) {
func (p *Program) Run(ctx context.Context, setters ...Option) (result []byte, err error) {
defer func() {
if r := recover(); r != nil {
// find out exactly what the error was and set err
switch x := r.(type) {
case string:
err = errors.New(x)
case error:
err = x
default:
err = errors.New("unknown panic")
}
result = nil
}
}()
scope, closeFn := core.NewRootScope()
defer closeFn()

View File

@ -0,0 +1,25 @@
package runtime_test
import (
"context"
"github.com/MontFerret/ferret/pkg/compiler"
"github.com/MontFerret/ferret/pkg/runtime/core"
. "github.com/smartystreets/goconvey/convey"
"testing"
)
func TestProgram(t *testing.T) {
Convey("Should recover from panic", t, func() {
c := compiler.New()
c.RegisterFunction("panic", func(ctx context.Context, args ...core.Value) (core.Value, error) {
panic("test")
})
p := c.MustCompile(`RETURN PANIC()`)
_, err := p.Run(context.Background())
So(err, ShouldBeError)
So(err.Error(), ShouldEqual, "test")
})
}