Skip to content

Commit

Permalink
fix: error instead of panic on int div-by-zero
Browse files Browse the repository at this point in the history
  • Loading branch information
docmerlin committed May 19, 2020
1 parent bf60b18 commit 50bffda
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 158 deletions.
5 changes: 2 additions & 3 deletions eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ func (n *EvalNode) newGroup() *evalGroup {
}
}

func (n *EvalNode) eval(expressions []stateful.Expression, p edge.FieldsTagsTimeSetter) error {

func (n *EvalNode) eval(expressions []stateful.Expression, p edge.FieldsTagsTimeSetter) (err error) {
vars := n.scopePool.Get()
defer n.scopePool.Put(vars)

Expand Down Expand Up @@ -172,7 +171,7 @@ func (n *EvalNode) eval(expressions []stateful.Expression, p edge.FieldsTagsTime
}
p.SetFields(newFields)
p.SetTags(newTags)
return nil
return
}

type evalGroup struct {
Expand Down
21 changes: 19 additions & 2 deletions integrations/streamer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"encoding/json"
"flag"
"fmt"
"github.com/influxdata/kapacitor/services/discord"
"github.com/influxdata/kapacitor/services/discord/discordtest"
"html"
"io/ioutil"
"math/rand"
Expand All @@ -23,6 +21,9 @@ import (
"text/template"
"time"

"github.com/influxdata/kapacitor/services/discord"
"github.com/influxdata/kapacitor/services/discord/discordtest"

"github.com/davecgh/go-spew/spew"
"github.com/docker/docker/api/types/swarm"
"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -2691,6 +2692,20 @@ stream
testStreamerWithOutput(t, "TestStream_EvalAllTypes", script, 2*time.Second, er, false, nil)
}

func TestStream_EvalDivisionByZero(t *testing.T) {
var script = `
stream
|from()
.measurement('data')
|eval(lambda: 10/"n")
.as('n')
|httpOut('TestStream_EvalDivisionByZero')
`

testStreamerNoOutput(t, "TestStream_EvalDivisionByZero", script, 2*time.Second, nil)

}

func TestStream_Eval_KeepAll(t *testing.T) {
var script = `
stream
Expand Down Expand Up @@ -12868,6 +12883,7 @@ func testStreamer(
<-chan error,
*kapacitor.TaskMaster,
) {
t.Helper()
if testing.Verbose() {
wlog.SetLevel(wlog.DEBUG)
} else {
Expand Down Expand Up @@ -13027,6 +13043,7 @@ func testStreamerWithOutput(
ignoreOrder bool,
tmInit func(tm *kapacitor.TaskMaster),
) {
t.Helper()
clock, et, replayErr, tm := testStreamer(t, name, script, tmInit)
defer tm.Close()

Expand Down
3 changes: 3 additions & 0 deletions integrations/testdata/TestStream_EvalDivisionByZero.srpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dbname
rpname
data,t=t1 n=0i 0000003600
33 changes: 24 additions & 9 deletions tick/stateful/expr.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package stateful

import (
"errors"
"fmt"
"time"

Expand Down Expand Up @@ -88,50 +89,64 @@ func (se *expression) EvalMissing(scope *Scope) (*ast.Missing, error) {
return se.nodeEvaluator.EvalMissing(scope, se.executionState)
}

func (se *expression) Eval(scope *Scope) (interface{}, error) {
typ, err := se.nodeEvaluator.Type(scope)
func (se *expression) Eval(scope *Scope) (result interface{}, err error) {
defer func() {
if r := recover(); r != nil {
switch r := r.(type) {
case string:
err = errors.New(r)
case error:
err = r
case fmt.Stringer:
err = errors.New(r.String())
}
}
}()
var typ ast.ValueType
typ, err = se.nodeEvaluator.Type(scope)
if err != nil {
return nil, err
}

switch typ {
case ast.TInt:
result, err := se.EvalInt(scope)
result, err = se.EvalInt(scope)
if err != nil {
return nil, err
}
return result, err
case ast.TFloat:
result, err := se.EvalFloat(scope)
result, err = se.EvalFloat(scope)
if err != nil {
return nil, err
}
return result, err
case ast.TString:
result, err := se.EvalString(scope)
result, err = se.EvalString(scope)
if err != nil {
return nil, err
}
return result, err
case ast.TBool:
result, err := se.EvalBool(scope)
result, err = se.EvalBool(scope)
if err != nil {
return nil, err
}
return result, err
case ast.TDuration:
result, err := se.EvalDuration(scope)
result, err = se.EvalDuration(scope)
if err != nil {
return nil, err
}
return result, err
case ast.TMissing:
result, err := se.EvalMissing(scope)
result, err = se.EvalMissing(scope)
if err != nil {
return nil, err
}
return result, err
default:
return nil, fmt.Errorf("expression returned unexpected type %s", typ)
err = fmt.Errorf("expression returned unexpected type %s", typ)
return
}
}
Loading

0 comments on commit 50bffda

Please sign in to comment.