mirror of
https://github.com/grafana/grafana.git
synced 2025-01-27 16:57:14 -06:00
Prometheus: Refactor error handling logic (#62254)
* Refactor error handling logic
- Enable query inspector to show error information
- Update naming
* Change fetch method return signature
* update the snapshot
* Revert "update the snapshot"
This reverts commit 28b26ce426
.
This commit is contained in:
parent
4186871390
commit
49258b135a
@ -97,10 +97,7 @@ func (s *QueryData) Execute(ctx context.Context, req *backend.QueryDataRequest)
|
||||
if err != nil {
|
||||
return &result, err
|
||||
}
|
||||
r, err := s.fetch(ctx, s.client, query, req.Headers)
|
||||
if err != nil {
|
||||
return &result, err
|
||||
}
|
||||
r := s.fetch(ctx, s.client, query, req.Headers)
|
||||
if r == nil {
|
||||
s.log.FromContext(ctx).Debug("Received nilresponse from runQuery", "query", query.Expr)
|
||||
continue
|
||||
@ -111,69 +108,75 @@ func (s *QueryData) Execute(ctx context.Context, req *backend.QueryDataRequest)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *QueryData) fetch(ctx context.Context, client *client.Client, q *models.Query, headers map[string]string) (*backend.DataResponse, error) {
|
||||
func (s *QueryData) fetch(ctx context.Context, client *client.Client, q *models.Query, headers map[string]string) *backend.DataResponse {
|
||||
traceCtx, end := s.trace(ctx, q)
|
||||
defer end()
|
||||
|
||||
logger := s.log.FromContext(traceCtx)
|
||||
logger.Debug("Sending query", "start", q.Start, "end", q.End, "step", q.Step, "query", q.Expr)
|
||||
|
||||
response := &backend.DataResponse{
|
||||
dr := &backend.DataResponse{
|
||||
Frames: data.Frames{},
|
||||
Error: nil,
|
||||
}
|
||||
|
||||
if q.InstantQuery {
|
||||
res, err := s.instantQuery(traceCtx, client, q, headers)
|
||||
response.Error = err
|
||||
response.Frames = res.Frames
|
||||
res := s.instantQuery(traceCtx, client, q, headers)
|
||||
dr.Error = res.Error
|
||||
dr.Frames = res.Frames
|
||||
}
|
||||
|
||||
if q.RangeQuery {
|
||||
res, err := s.rangeQuery(traceCtx, client, q, headers)
|
||||
if err != nil {
|
||||
if response.Error == nil {
|
||||
response.Error = err
|
||||
res := s.rangeQuery(traceCtx, client, q, headers)
|
||||
if res.Error != nil {
|
||||
if dr.Error == nil {
|
||||
dr.Error = res.Error
|
||||
} else {
|
||||
response.Error = fmt.Errorf("%v %w", response.Error, err)
|
||||
dr.Error = fmt.Errorf("%v %w", dr.Error, res.Error)
|
||||
}
|
||||
}
|
||||
response.Frames = append(response.Frames, res.Frames...)
|
||||
dr.Frames = append(dr.Frames, res.Frames...)
|
||||
}
|
||||
|
||||
if q.ExemplarQuery {
|
||||
res, err := s.exemplarQuery(traceCtx, client, q, headers)
|
||||
if err != nil {
|
||||
res := s.exemplarQuery(traceCtx, client, q, headers)
|
||||
if res.Error != nil {
|
||||
// If exemplar query returns error, we want to only log it and
|
||||
// continue with other results processing
|
||||
logger.Error("Exemplar query failed", "query", q.Expr, "err", err)
|
||||
logger.Error("Exemplar query failed", "query", q.Expr, "err", res.Error)
|
||||
}
|
||||
response.Frames = append(response.Frames, res.Frames...)
|
||||
dr.Frames = append(dr.Frames, res.Frames...)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
return dr
|
||||
}
|
||||
|
||||
func (s *QueryData) rangeQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) (backend.DataResponse, error) {
|
||||
func (s *QueryData) rangeQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) backend.DataResponse {
|
||||
res, err := c.QueryRange(ctx, q)
|
||||
if err != nil {
|
||||
return backend.DataResponse{}, err
|
||||
return backend.DataResponse{
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
return s.parseResponse(ctx, q, res)
|
||||
}
|
||||
|
||||
func (s *QueryData) instantQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) (backend.DataResponse, error) {
|
||||
func (s *QueryData) instantQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) backend.DataResponse {
|
||||
res, err := c.QueryInstant(ctx, q)
|
||||
if err != nil {
|
||||
return backend.DataResponse{}, err
|
||||
return backend.DataResponse{
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
return s.parseResponse(ctx, q, res)
|
||||
}
|
||||
|
||||
func (s *QueryData) exemplarQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) (backend.DataResponse, error) {
|
||||
func (s *QueryData) exemplarQuery(ctx context.Context, c *client.Client, q *models.Query, headers map[string]string) backend.DataResponse {
|
||||
res, err := c.QueryExemplars(ctx, q)
|
||||
if err != nil {
|
||||
return backend.DataResponse{}, err
|
||||
return backend.DataResponse{
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
return s.parseResponse(ctx, q, res)
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util/converter"
|
||||
)
|
||||
|
||||
func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *http.Response) (backend.DataResponse, error) {
|
||||
func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *http.Response) backend.DataResponse {
|
||||
defer func() {
|
||||
if err := res.Body.Close(); err != nil {
|
||||
s.log.FromContext(ctx).Error("Failed to close response body", "err", err)
|
||||
@ -30,6 +30,12 @@ func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *htt
|
||||
VectorWideSeries: s.enableWideSeries,
|
||||
})
|
||||
|
||||
// Add frame to attach metadata
|
||||
if len(r.Frames) == 0 && !q.ExemplarQuery {
|
||||
r.Frames = append(r.Frames, data.NewFrame(""))
|
||||
}
|
||||
|
||||
// The ExecutedQueryString can be viewed in QueryInspector in UI
|
||||
for _, frame := range r.Frames {
|
||||
if s.enableWideSeries {
|
||||
addMetadataToWideFrame(q, frame)
|
||||
@ -38,12 +44,11 @@ func (s *QueryData) parseResponse(ctx context.Context, q *models.Query, res *htt
|
||||
}
|
||||
}
|
||||
|
||||
if r.Error != nil {
|
||||
return r, r.Error
|
||||
if r.Error == nil {
|
||||
r = s.processExemplars(q, r)
|
||||
}
|
||||
|
||||
r = s.processExemplars(q, r)
|
||||
return r, nil
|
||||
return r
|
||||
}
|
||||
|
||||
func (s *QueryData) processExemplars(q *models.Query, dr backend.DataResponse) backend.DataResponse {
|
||||
|
Loading…
Reference in New Issue
Block a user