mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-16 11:37:36 +02:00
Added panic recovery mechanism (#158)
This commit is contained in:
parent
4032e8dd7c
commit
5e6701f1c1
@ -59,9 +59,6 @@ func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error
|
|||||||
return nil, ErrEmptyQuery
|
return nil, ErrEmptyQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
p := parser.New(query)
|
|
||||||
p.AddErrorListener(&errorListener{})
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
// find out exactly what the error was and set err
|
// 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)
|
l := newVisitor(query, c.funcs)
|
||||||
|
|
||||||
res := p.Visit(l).(*result)
|
res := p.Visit(l).(*result)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/MontFerret/ferret/pkg/html"
|
"github.com/MontFerret/ferret/pkg/html"
|
||||||
"github.com/MontFerret/ferret/pkg/runtime/core"
|
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||||||
"github.com/MontFerret/ferret/pkg/runtime/values"
|
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Program struct {
|
type Program struct {
|
||||||
@ -28,7 +29,23 @@ func (p *Program) Source() string {
|
|||||||
return p.src
|
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()
|
scope, closeFn := core.NewRootScope()
|
||||||
|
|
||||||
defer closeFn()
|
defer closeFn()
|
||||||
|
25
pkg/runtime/program_test.go
Normal file
25
pkg/runtime/program_test.go
Normal 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")
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user