From 5e8294c9d3c5e4dcbd75e3314abaab781bbbb3fe Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Tue, 21 Oct 2025 11:58:30 +0200 Subject: [PATCH] Chore: Mark prometheus query json unmarshaling errors as downstream error (#112314) * mark json unmarshaling errors as downstream * shortcut --- pkg/promlib/models/query.go | 6 ++++-- pkg/promlib/models/query_test.go | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pkg/promlib/models/query.go b/pkg/promlib/models/query.go index c2ea3305d0b..c0c7aaf1755 100644 --- a/pkg/promlib/models/query.go +++ b/pkg/promlib/models/query.go @@ -13,11 +13,13 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/gtime" sdkapi "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" - scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" + scope "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1" + glog "github.com/grafana/grafana-plugin-sdk-go/backend/log" + "github.com/grafana/grafana/pkg/promlib/intervalv2" ) @@ -164,7 +166,7 @@ type internalQueryModel struct { func Parse(ctx context.Context, log glog.Logger, span trace.Span, query backend.DataQuery, dsScrapeInterval string, intervalCalculator intervalv2.Calculator, fromAlert bool) (*Query, error) { model := &internalQueryModel{} if err := json.Unmarshal(query.JSON, model); err != nil { - return nil, err + return nil, backend.DownstreamErrorf("error unmarshaling query: %w", err) } span.SetAttributes(attribute.String("rawExpr", model.Expr)) diff --git a/pkg/promlib/models/query_test.go b/pkg/promlib/models/query_test.go index 3cf9fe53405..643e0d9d548 100644 --- a/pkg/promlib/models/query_test.go +++ b/pkg/promlib/models/query_test.go @@ -1307,6 +1307,40 @@ func TestParseComplexScenariosWithFilters(t *testing.T) { }) } +func TestParseNumericFormatError(t *testing.T) { + _, span := tracer.Start(context.Background(), "operation") + defer span.End() + + timeRange := backend.TimeRange{ + From: now, + To: now.Add(12 * time.Hour), + } + + // Test case where format is sent as a number instead of string + queryJson := `{ + "expr": "up", + "format": 0, + "refId": "A" + }` + + q := backend.DataQuery{ + JSON: []byte(queryJson), + TimeRange: timeRange, + RefID: "A", + } + + res, err := models.Parse(context.Background(), log.New(), span, q, "15s", intervalCalculator, false) + + require.Error(t, err) + require.Nil(t, res) + + require.True(t, backend.IsDownstreamError(err)) + + // Error message should indicate unmarshaling issue + require.Contains(t, err.Error(), "error unmarshaling query") + require.Contains(t, err.Error(), "cannot unmarshal number") +} + func TestQueryTypeDefinitions(t *testing.T) { builder, err := schemabuilder.NewSchemaBuilder( schemabuilder.BuilderOptions{