Merge pull request #2197 from tcolgate/fix_error_types

Report type names in the form used in documentation
This commit is contained in:
Fabian Reinartz 2016-11-21 09:49:49 +01:00 committed by GitHub
commit 0b1a07b531
3 changed files with 36 additions and 21 deletions

View File

@ -120,7 +120,7 @@ func (r *Result) Matrix() (model.Matrix, error) {
}
v, ok := r.Value.(model.Matrix)
if !ok {
return nil, fmt.Errorf("query result is not a matrix")
return nil, fmt.Errorf("query result is not a range vector")
}
return v, nil
}
@ -286,7 +286,7 @@ func (ng *Engine) NewRangeQuery(qs string, start, end model.Time, interval time.
return nil, err
}
if expr.Type() != model.ValVector && expr.Type() != model.ValScalar {
return nil, fmt.Errorf("invalid expression type %q for range query, must be scalar or vector", expr.Type())
return nil, fmt.Errorf("invalid expression type %q for range query, must be scalar or instant vector", documentedType(expr.Type()))
}
qry := ng.newQuery(expr, start, end, interval)
qry.q = qs
@ -581,7 +581,7 @@ func (ev *evaluator) evalScalar(e Expr) *model.Scalar {
val := ev.eval(e)
sv, ok := val.(*model.Scalar)
if !ok {
ev.errorf("expected scalar but got %s", val.Type())
ev.errorf("expected scalar but got %s", documentedType(val.Type()))
}
return sv
}
@ -591,7 +591,7 @@ func (ev *evaluator) evalVector(e Expr) vector {
val := ev.eval(e)
vec, ok := val.(vector)
if !ok {
ev.errorf("expected vector but got %s", val.Type())
ev.errorf("expected instant vector but got %s", documentedType(val.Type()))
}
return vec
}
@ -612,11 +612,13 @@ func (ev *evaluator) evalFloat(e Expr) float64 {
}
// evalMatrix attempts to evaluate e into a matrix and errors otherwise.
// The error message uses the term "range vector" to match the user facing
// documentation.
func (ev *evaluator) evalMatrix(e Expr) matrix {
val := ev.eval(e)
mat, ok := val.(matrix)
if !ok {
ev.errorf("expected matrix but got %s", val.Type())
ev.errorf("expected range vector but got %s", documentedType(val.Type()))
}
return mat
}
@ -626,7 +628,7 @@ func (ev *evaluator) evalString(e Expr) *model.String {
val := ev.eval(e)
sv, ok := val.(*model.String)
if !ok {
ev.errorf("expected string but got %s", val.Type())
ev.errorf("expected string but got %s", documentedType(val.Type()))
}
return sv
}
@ -635,7 +637,7 @@ func (ev *evaluator) evalString(e Expr) *model.String {
func (ev *evaluator) evalOneOf(e Expr, t1, t2 model.ValueType) model.Value {
val := ev.eval(e)
if val.Type() != t1 && val.Type() != t2 {
ev.errorf("expected %s or %s but got %s", t1, t2, val.Type())
ev.errorf("expected %s or %s but got %s", documentedType(t1), documentedType(t2), documentedType(val.Type()))
}
return val
}
@ -1337,3 +1339,16 @@ func (g *queryGate) Done() {
panic("engine.queryGate.Done: more operations done than started")
}
}
// documentedType returns the internal type to the equivalent
// user facing terminology as defined in the documentation.
func documentedType(t model.ValueType) string {
switch t.String() {
case "vector":
return "instant vector"
case "matrix":
return "range vector"
default:
return t.String()
}
}

View File

@ -990,7 +990,7 @@ func (p *parser) vectorSelector(name string) *VectorSelector {
func (p *parser) expectType(node Node, want model.ValueType, context string) {
t := p.checkType(node)
if t != want {
p.errorf("expected type %s in %s, got %s", want, context, t)
p.errorf("expected type %s in %s, got %s", documentedType(want), context, documentedType(t))
}
}
@ -1024,20 +1024,20 @@ func (p *parser) checkType(node Node) (typ model.ValueType) {
case *EvalStmt:
ty := p.checkType(n.Expr)
if ty == model.ValNone {
p.errorf("evaluation statement must have a valid expression type but got %s", ty)
p.errorf("evaluation statement must have a valid expression type but got %s", documentedType(ty))
}
case *RecordStmt:
ty := p.checkType(n.Expr)
if ty != model.ValVector && ty != model.ValScalar {
p.errorf("record statement must have a valid expression of type vector or scalar but got %s", ty)
p.errorf("record statement must have a valid expression of type instant vector or scalar but got %s", documentedType(ty))
}
case Expressions:
for _, e := range n {
ty := p.checkType(e)
if ty == model.ValNone {
p.errorf("expression must have a valid expression type but got %s", ty)
p.errorf("expression must have a valid expression type but got %s", documentedType(ty))
}
}
case *AggregateExpr:
@ -1060,12 +1060,12 @@ func (p *parser) checkType(node Node) (typ model.ValueType) {
p.errorf("binary expression does not support operator %q", n.Op)
}
if (lt != model.ValScalar && lt != model.ValVector) || (rt != model.ValScalar && rt != model.ValVector) {
p.errorf("binary expression must contain only scalar and vector types")
p.errorf("binary expression must contain only scalar and instant vector types")
}
if (lt != model.ValVector || rt != model.ValVector) && n.VectorMatching != nil {
if len(n.VectorMatching.MatchingLabels) > 0 {
p.errorf("vector matching only allowed between vectors")
p.errorf("vector matching only allowed between instant vectors")
}
n.VectorMatching = nil
} else {
@ -1104,7 +1104,7 @@ func (p *parser) checkType(node Node) (typ model.ValueType) {
p.errorf("only + and - operators allowed for unary expressions")
}
if t := p.checkType(n.Expr); t != model.ValScalar && t != model.ValVector {
p.errorf("unary expression only allowed on expressions of type scalar or vector, got %q", t)
p.errorf("unary expression only allowed on expressions of type scalar or instant vector, got %q", documentedType(t))
}
case *NumberLiteral, *MatrixSelector, *StringLiteral, *VectorSelector:

View File

@ -237,11 +237,11 @@ var testExpr = []struct {
}, {
input: `-"string"`,
fail: true,
errMsg: `unary expression only allowed on expressions of type scalar or vector, got "string"`,
errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "string"`,
}, {
input: `-test[5m]`,
fail: true,
errMsg: `unary expression only allowed on expressions of type scalar or vector, got "matrix"`,
errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "range vector"`,
}, {
input: `*test`,
fail: true,
@ -772,11 +772,11 @@ var testExpr = []struct {
}, {
input: "1 or on(bar) foo",
fail: true,
errMsg: "vector matching only allowed between vectors",
errMsg: "vector matching only allowed between instant vectors",
}, {
input: "foo == on(bar) 10",
fail: true,
errMsg: "vector matching only allowed between vectors",
errMsg: "vector matching only allowed between instant vectors",
}, {
input: "foo and on(bar) group_left(baz) bar",
fail: true,
@ -1286,7 +1286,7 @@ var testExpr = []struct {
}, {
input: `topk(some_metric, other_metric)`,
fail: true,
errMsg: "parse error at char 32: expected type scalar in aggregation parameter, got vector",
errMsg: "parse error at char 32: expected type scalar in aggregation parameter, got instant vector",
}, {
input: `count_values(5, other_metric)`,
fail: true,
@ -1364,7 +1364,7 @@ var testExpr = []struct {
}, {
input: "floor(1)",
fail: true,
errMsg: "expected type vector in call to function \"floor\", got scalar",
errMsg: "expected type instant vector in call to function \"floor\", got scalar",
}, {
input: "non_existent_function_far_bar()",
fail: true,
@ -1372,7 +1372,7 @@ var testExpr = []struct {
}, {
input: "rate(some_metric)",
fail: true,
errMsg: "expected type matrix in call to function \"rate\", got vector",
errMsg: "expected type range vector in call to function \"rate\", got instant vector",
},
// Fuzzing regression tests.
{