diff --git a/pkg/quickwit/client/client.go b/pkg/quickwit/client/client.go index 8124781..f24bce7 100644 --- a/pkg/quickwit/client/client.go +++ b/pkg/quickwit/client/client.go @@ -167,10 +167,17 @@ func (c *baseClientImpl) ExecuteMultisearch(r *MultiSearchRequest) (*MultiSearch c.logger.Debug("Received multisearch response", "code", res.StatusCode, "status", res.Status, "content-length", res.ContentLength) if res.StatusCode >= 400 { - jsonResponseBody, _ := json.Marshal(res.Body) - jsonQueryParam, _ := json.Marshal(queryParams) - jsonRequestBody, _ := json.Marshal(r.Requests) - c.logger.Error("Error on multisearch: statusCode = " + strconv.Itoa(res.StatusCode) + ", responseBody = " + string(jsonResponseBody) + ", queryParam = " + string(jsonQueryParam) + ", requestBody = " + string(jsonRequestBody)) + qe := QuickwitQueryError{ + Status: res.StatusCode, + Message: "Error on multisearch", + ResponseBody: res.Body, + QueryParam: queryParams, + RequestBody: r.Requests, + } + + errorPayload, _ := json.Marshal(qe) + c.logger.Error(string(errorPayload)) + return nil, fmt.Errorf(string(errorPayload)) } start := time.Now() diff --git a/pkg/quickwit/client/models.go b/pkg/quickwit/client/models.go index 84c93db..e4769e1 100644 --- a/pkg/quickwit/client/models.go +++ b/pkg/quickwit/client/models.go @@ -2,6 +2,7 @@ package es import ( "encoding/json" + "io" "time" ) @@ -43,6 +44,14 @@ type SearchResponseHits struct { Hits []map[string]interface{} } +type QuickwitQueryError struct { + Status int `json:"status"` + Message string `json:"message"` + ResponseBody io.ReadCloser `json:"response_body"` + RequestBody []*SearchRequest `json:"request_body"` + QueryParam string `json:"query_param"` +} + // SearchResponse represents a search response type SearchResponse struct { Error map[string]interface{} `json:"error"` diff --git a/pkg/quickwit/data_query.go b/pkg/quickwit/data_query.go index 0bfb0be..950cf10 100644 --- a/pkg/quickwit/data_query.go +++ b/pkg/quickwit/data_query.go @@ -1,13 +1,13 @@ package quickwit import ( + "encoding/json" "fmt" "regexp" "strconv" "time" "github.com/grafana/grafana-plugin-sdk-go/backend" - es "github.com/quickwit-oss/quickwit-datasource/pkg/quickwit/client" "github.com/quickwit-oss/quickwit-datasource/pkg/quickwit/simplejson" ) @@ -28,6 +28,26 @@ var newElasticsearchDataQuery = func(client es.Client, dataQuery []backend.DataQ } } +func handleQuickwitErrors(e *elasticsearchDataQuery, err error) (*backend.QueryDataResponse, error) { + if nil == err { + return nil, nil + } + + var payload = err.Error() + var qe es.QuickwitQueryError + unmarshall_err := json.Unmarshal([]byte(payload), &qe) + if unmarshall_err == nil { + return nil, err + } + + result := backend.QueryDataResponse{ + Responses: backend.Responses{}, + } + + result.Responses[e.dataQueries[0].RefID] = backend.ErrDataResponse(backend.Status(qe.Status), payload) + return &result, nil +} + func (e *elasticsearchDataQuery) execute() (*backend.QueryDataResponse, error) { queries, err := parseQuery(e.dataQueries) if err != nil { @@ -50,14 +70,13 @@ func (e *elasticsearchDataQuery) execute() (*backend.QueryDataResponse, error) { } res, err := e.client.ExecuteMultisearch(req) - if err != nil { + result, err := handleQuickwitErrors(e, err) + if result != nil { + return result, nil + } else if err != nil { return &backend.QueryDataResponse{}, err } - if res.Status == 404 { - return &backend.QueryDataResponse{}, fmt.Errorf("/_msearch endpoint not found, please check your Quickwit version") - } - return parseResponse(res.Responses, queries, e.client.GetConfiguredFields()) } diff --git a/pkg/quickwit/error_handling_test.go b/pkg/quickwit/error_handling_test.go index d1964d6..7ce7c21 100644 --- a/pkg/quickwit/error_handling_test.go +++ b/pkg/quickwit/error_handling_test.go @@ -44,11 +44,10 @@ func TestErrorAvgMissingField(t *testing.T) { LogMessageField: "line", LogLevelField: "lvl", } - result, err := queryDataTestWithResponseCode(query, 400, response, configuredFields) - require.NoError(t, err) - // FIXME: we should return the received error message - require.Len(t, result.response.Responses, 0) + result, err := queryDataTestWithResponseCode(query, 400, response, configuredFields) + require.Nil(t, err) + require.Contains(t, result.response.Responses["A"].Error.Error(), "\"status\":400") } func TestErrorAvgMissingFieldNoDetailedErrors(t *testing.T) { @@ -78,11 +77,10 @@ func TestErrorAvgMissingFieldNoDetailedErrors(t *testing.T) { LogMessageField: "line", LogLevelField: "lvl", } - result, err := queryDataTestWithResponseCode(query, 400, response, configuredFields) - require.NoError(t, err) - // FIXME: we should return the received error message - require.Len(t, result.response.Responses, 0) + result, err := queryDataTestWithResponseCode(query, 400, response, configuredFields) + require.Nil(t, err) + require.Contains(t, result.response.Responses["A"].Error.Error(), "\"status\":400") } func TestErrorTooManyDateHistogramBuckets(t *testing.T) { @@ -164,11 +162,8 @@ func TestNonElasticError(t *testing.T) { LogMessageField: "line", LogLevelField: "lvl", } - _, err := queryDataTestWithResponseCode(query, 403, response, configuredFields) - // FIXME: we should return something better. - // currently it returns the error-message about being unable to decode JSON - // it is not 100% clear what we should return to the browser - // (and what to debug-log for example), we could return - // at least something like "unknown response, http status code 403" - require.ErrorContains(t, err, "invalid character") + + result, err := queryDataTestWithResponseCode(query, 403, response, configuredFields) + require.Nil(t, err) + require.Contains(t, result.response.Responses["A"].Error.Error(), "\"status\":403") } diff --git a/src/datasource.ts b/src/datasource.ts index 36af503..36cd0a2 100644 --- a/src/datasource.ts +++ b/src/datasource.ts @@ -125,8 +125,7 @@ export class QuickwitDataSource catchError((err) => { if (err.status === 404) { return of({ status: 'error', message: 'Index does not exists.' }); - } - else if (err.message) { + } else if (err.message) { return of({ status: 'error', message: err.message }); } else { return of({ status: 'error', message: err.status }); @@ -487,7 +486,7 @@ export class QuickwitDataSource const error: DataQueryError = { message: 'Error during context query. Please check JS console logs.', status: err.status, - statusText: err.statusText, + statusText: err.message, }; throw error; })