From 2d1271e9818f5bded00eebaa5c27e690acec5abb Mon Sep 17 00:00:00 2001 From: Adam Simpson Date: Thu, 31 Jul 2025 14:10:21 -0400 Subject: [PATCH] query service: improve error handling and logging (#108948) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sarah Zinger sarah.zinger@grafana.com Co-authored-by: Gábor Farkas gabor.farkas@gmail.com --- pkg/registry/apis/query/query.go | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/pkg/registry/apis/query/query.go b/pkg/registry/apis/query/query.go index 6e73e9dd63d..a70aa657765 100644 --- a/pkg/registry/apis/query/query.go +++ b/pkg/registry/apis/query/query.go @@ -3,9 +3,11 @@ package query import ( "context" "encoding/json" + "errors" "net/http" "slices" "strconv" + "strings" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1" @@ -187,9 +189,25 @@ func (r *queryREST) Connect(connectCtx context.Context, name string, _ runtime.O }) return } else { - // return the error to the client, will send all non k8s errors as a k8 unexpected error - b.log.Error("hit unexpected error while executing query, this will show as an unhandled k8s status error", "err", err) - responder.Error(err) + var errorDataResponse backend.DataResponse + if errors.Is(err, service.ErrInvalidDatasourceID) || errors.Is(err, service.ErrNoQueriesFound) || errors.Is(err, service.ErrMissingDataSourceInfo) || errors.Is(err, service.ErrQueryParamMismatch) || errors.Is(err, service.ErrDuplicateRefId) { + errorDataResponse = backend.ErrDataResponseWithSource(backend.StatusBadRequest, backend.ErrorSourceDownstream, err.Error()) + } else if strings.Contains(err.Error(), "expression request error") { + b.log.Error("Error calling TransformData in an expression", "err", err) + errorDataResponse = backend.ErrDataResponseWithSource(backend.StatusBadRequest, backend.ErrorSourceDownstream, err.Error()) + } else { + b.log.Error("unknown error, treated as a 500", "err", err) + responder.Error(err) + return + } + qdr = &backend.QueryDataResponse{ + Responses: map[string]backend.DataResponse{ + "A": errorDataResponse, + }, + } + responder.Object(query.GetResponseCode(qdr), &query.QueryDataResponse{ + QueryDataResponse: *qdr, + }) return } } @@ -215,6 +233,7 @@ func handleQuery(ctx context.Context, raw query.QueryDataRequest, b QueryAPIBuil jsonQueries = append(jsonQueries, sjQuery) } + mReq := dtos.MetricRequest{ From: raw.From, To: raw.To, @@ -234,7 +253,7 @@ func handleQuery(ctx context.Context, raw query.QueryDataRequest, b QueryAPIBuil return nil, err } - dsQuerierLoggerWithSlug := connectLogger.New("slug", instanceConfig.Options["slug"]) + dsQuerierLoggerWithSlug := connectLogger.New("slug", instanceConfig.Options["slug"], "ruleuid", headers["X-Rule-Uid"]) mtDsClientBuilder := mtdsclient.NewMtDatasourceClientBuilderWithClientSupplier( b.clientSupplier,