GCM: Add errorsource (#92151)

* Add errorsource

* Minor lint fixes
This commit is contained in:
Andreas Christou 2024-09-10 19:34:20 +01:00 committed by GitHub
parent acbd50c7d6
commit 00ace4678c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 41 additions and 30 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
)
type annotationEvent struct {
@ -24,6 +25,7 @@ func (s *Service) executeAnnotationQuery(ctx context.Context, req *backend.Query
resp := backend.NewQueryDataResponse()
queryRes, dr, _, err := queries[0].run(ctx, req, s, dsInfo, logger)
if err != nil {
errorsource.AddErrorToResponse(queries[0].getRefID(), resp, err)
return resp, err
}
@ -42,6 +44,11 @@ func (s *Service) executeAnnotationQuery(ctx context.Context, req *backend.Query
err = parseToAnnotations(req.Queries[0].RefID, queryRes, dr.(cloudMonitoringResponse), tslq.TimeSeriesList.Title, tslq.TimeSeriesList.Text)
resp.Responses[firstQuery.RefID] = *queryRes
if err != nil {
errorsource.AddErrorToResponse(firstQuery.RefID, resp, err)
return resp, err
}
return resp, err
}

View File

@ -22,6 +22,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"github.com/grafana/grafana/pkg/tsdb/cloud-monitoring/kinds/dataquery"
)
@ -342,6 +343,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
return nil, err
}
// There aren't any possible downstream errors here
queries, err := s.buildQueryExecutors(logger, req)
if err != nil {
return nil, err
@ -361,11 +363,15 @@ func (s *Service) executeTimeSeriesQuery(ctx context.Context, req *backend.Query
for _, queryExecutor := range queries {
queryRes, dr, executedQueryString, err := queryExecutor.run(ctx, req, s, dsInfo, logger)
if err != nil {
errorsource.AddErrorToResponse(queryExecutor.getRefID(), resp, err)
return resp, err
}
err = queryExecutor.parseResponse(queryRes, dr, executedQueryString, logger)
if err != nil {
queryRes.Error = err
// Default to a plugin error if there's no source
errWithSource := errorsource.SourceError(backend.ErrorSourcePlugin, err, false)
queryRes.Error = errWithSource.Unwrap()
queryRes.ErrorSource = errWithSource.ErrorSource()
}
resp.Responses[queryExecutor.getRefID()] = *queryRes
@ -583,7 +589,8 @@ func (s *Service) ensureProject(ctx context.Context, dsInfo datasourceInfo, proj
func (s *Service) getDefaultProject(ctx context.Context, dsInfo datasourceInfo) (string, error) {
if dsInfo.authenticationType == gceAuthentication {
return s.gceDefaultProjectGetter(ctx, cloudMonitorScope)
project, err := s.gceDefaultProjectGetter(ctx, cloudMonitorScope)
return project, errorsource.DownstreamError(err, false)
}
return dsInfo.defaultProject, nil
}
@ -602,7 +609,7 @@ func unmarshalResponse(res *http.Response, logger log.Logger) (cloudMonitoringRe
if res.StatusCode/100 != 2 {
logger.Error("Request failed", "status", res.Status, "body", string(body))
return cloudMonitoringResponse{}, fmt.Errorf("query failed: %s", string(body))
return cloudMonitoringResponse{}, errorsource.SourceError(backend.ErrorSourceFromHTTPStatus(res.StatusCode), fmt.Errorf("query failed: %s", string(body)), false)
}
var data cloudMonitoringResponse

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"github.com/grafana/grafana/pkg/tsdb/cloud-monitoring/converter"
jsoniter "github.com/json-iterator/go"
)
@ -22,8 +23,7 @@ func (promQLQ *cloudMonitoringProm) run(ctx context.Context, req *backend.QueryD
dr := &backend.DataResponse{}
projectName, err := s.ensureProject(ctx, dsInfo, promQLQ.parameters.ProjectName)
if err != nil {
dr.Error = err
return dr, backend.DataResponse{}, "", nil
return dr, backend.DataResponse{}, "", err
}
r, err := createRequest(ctx, &dsInfo, path.Join("/v1/projects", projectName, "location/global/prometheus/api/v1/query_range"), nil)
if err != nil {
@ -43,8 +43,7 @@ func (promQLQ *cloudMonitoringProm) run(ctx context.Context, req *backend.QueryD
res, err := doRequestProm(r, dsInfo, requestBody)
if err != nil {
dr.Error = err
return dr, backend.DataResponse{}, "", nil
return dr, backend.DataResponse{}, "", err
}
defer func() {
@ -67,7 +66,7 @@ func doRequestProm(r *http.Request, dsInfo datasourceInfo, body map[string]any)
}
res, err := dsInfo.services[cloudMonitor].client.Do(r)
if err != nil {
return res, err
return res, errorsource.DownstreamError(err, false)
}
return res, nil

View File

@ -58,11 +58,11 @@ func TestPromqlQuery(t *testing.T) {
},
}
dr, parsedProm, _, _ := query.run(context.Background(), &backend.QueryDataRequest{}, service, dsInfo, service.logger)
require.Error(t, dr.Error)
require.Equal(t, "not found!", dr.Error.Error())
dr, parsedProm, _, err := query.run(context.Background(), &backend.QueryDataRequest{}, service, dsInfo, service.logger)
require.Error(t, err)
require.Equal(t, "not found!", err.Error())
err := query.parseResponse(dr, parsedProm, "", service.logger)
err = query.parseResponse(dr, parsedProm, "", service.logger)
require.NoError(t, err)
})
}

View File

@ -21,7 +21,7 @@ func (timeSeriesFilter *cloudMonitoringTimeSeriesList) run(ctx context.Context,
}
func parseTimeSeriesResponse(queryRes *backend.DataResponse,
response cloudMonitoringResponse, executedQueryString string, query cloudMonitoringQueryExecutor, params url.Values, groupBys []string, logger log.Logger) error {
response cloudMonitoringResponse, executedQueryString string, query cloudMonitoringQueryExecutor, params url.Values, groupBys []string, _ log.Logger) error {
frames := data.Frames{}
for _, series := range response.TimeSeries {

View File

@ -18,6 +18,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/experimental/errorsource"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
@ -28,15 +29,15 @@ func addInterval(period string, field *data.Field) error {
if err != nil {
return err
}
if err == nil {
if field.Config != nil {
field.Config.Interval = float64(p.Milliseconds())
} else {
field.SetConfig(&data.FieldConfig{
Interval: float64(p.Milliseconds()),
})
}
if field.Config != nil {
field.Config.Interval = float64(p.Milliseconds())
} else {
field.SetConfig(&data.FieldConfig{
Interval: float64(p.Milliseconds()),
})
}
return nil
}
@ -70,7 +71,7 @@ func createRequest(ctx context.Context, dsInfo *datasourceInfo, proxyPass string
return req, nil
}
func doRequestPage(ctx context.Context, r *http.Request, dsInfo datasourceInfo, params url.Values, body map[string]any, logger log.Logger) (cloudMonitoringResponse, error) {
func doRequestPage(_ context.Context, r *http.Request, dsInfo datasourceInfo, params url.Values, body map[string]any, logger log.Logger) (cloudMonitoringResponse, error) {
if params != nil {
r.URL.RawQuery = params.Encode()
}
@ -84,7 +85,7 @@ func doRequestPage(ctx context.Context, r *http.Request, dsInfo datasourceInfo,
}
res, err := dsInfo.services[cloudMonitor].client.Do(r)
if err != nil {
return cloudMonitoringResponse{}, err
return cloudMonitoringResponse{}, errorsource.DownstreamError(err, false)
}
defer func() {
@ -124,7 +125,7 @@ func doRequestWithPagination(ctx context.Context, r *http.Request, dsInfo dataso
return d, nil
}
func traceReq(ctx context.Context, req *backend.QueryDataRequest, dsInfo datasourceInfo, r *http.Request, target string) trace.Span {
func traceReq(ctx context.Context, req *backend.QueryDataRequest, dsInfo datasourceInfo, _ *http.Request, target string) trace.Span {
_, span := tracing.DefaultTracer().Start(ctx, "cloudMonitoring query", trace.WithAttributes(
attribute.String("target", target),
attribute.String("from", req.Queries[0].TimeRange.From.String()),
@ -141,8 +142,7 @@ func runTimeSeriesRequest(ctx context.Context, req *backend.QueryDataRequest,
dr := &backend.DataResponse{}
projectName, err := s.ensureProject(ctx, dsInfo, projectName)
if err != nil {
dr.Error = err
return dr, cloudMonitoringResponse{}, "", nil
return dr, cloudMonitoringResponse{}, "", err
}
timeSeriesMethod := "timeSeries"
if body != nil {
@ -150,8 +150,7 @@ func runTimeSeriesRequest(ctx context.Context, req *backend.QueryDataRequest,
}
r, err := createRequest(ctx, &dsInfo, path.Join("/v3/projects", projectName, timeSeriesMethod), nil)
if err != nil {
dr.Error = err
return dr, cloudMonitoringResponse{}, "", nil
return dr, cloudMonitoringResponse{}, "", err
}
span := traceReq(ctx, req, dsInfo, r, params.Encode())
@ -159,8 +158,7 @@ func runTimeSeriesRequest(ctx context.Context, req *backend.QueryDataRequest,
d, err := doRequestWithPagination(ctx, r, dsInfo, params, body, logger)
if err != nil {
dr.Error = err
return dr, cloudMonitoringResponse{}, "", nil
return dr, cloudMonitoringResponse{}, "", err
}
return dr, d, r.URL.RawQuery, nil