diff --git a/pkg/quickwit/quickwit.go b/pkg/quickwit/quickwit.go index 36ba450..c582808 100644 --- a/pkg/quickwit/quickwit.go +++ b/pkg/quickwit/quickwit.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -37,6 +38,23 @@ type QuickwitMapping struct { } `json:"index_config"` } +type QuickwitCreationErrorPayload struct { + Message string `json:"message"` + StatusCode int `json:"status"` +} + +func marshallErrorAsException(statusCode int, message string) error { + var payload QuickwitCreationErrorPayload + payload.Message = message + payload.StatusCode = statusCode + json, err := json.Marshal(payload) + if nil != err { + return err + } + + return errors.New(string(json)) +} + func getTimestampFieldInfos(index string, qwUrl string, cli *http.Client) (string, string, error) { mappingEndpointUrl := qwUrl + "/indexes/" + index qwlog.Info("Calling quickwit endpoint: " + mappingEndpointUrl) @@ -48,10 +66,11 @@ func getTimestampFieldInfos(index string, qwUrl string, cli *http.Client) (strin } statusCode := r.StatusCode + if statusCode < 200 || statusCode >= 400 { - errMsg := fmt.Sprintf("Error when calling url = %s: statusCode = %d", mappingEndpointUrl, statusCode) + errMsg := fmt.Sprintf("Error when calling url = %s", mappingEndpointUrl) qwlog.Error(errMsg) - return "", "", fmt.Errorf(errMsg) + return "", "", marshallErrorAsException(statusCode, errMsg) } defer r.Body.Close() @@ -59,7 +78,7 @@ func getTimestampFieldInfos(index string, qwUrl string, cli *http.Client) (strin if err != nil { errMsg := fmt.Sprintf("Error when calling url = %s: err = %s", mappingEndpointUrl, err.Error()) qwlog.Error(errMsg) - return "", "", err + return "", "", marshallErrorAsException(statusCode, errMsg) } var payload QuickwitMapping @@ -67,7 +86,7 @@ func getTimestampFieldInfos(index string, qwUrl string, cli *http.Client) (strin if err != nil { errMsg := fmt.Sprintf("Unmarshalling body error: err = %s, body = %s", err.Error(), (body)) qwlog.Error(errMsg) - return "", "", fmt.Errorf(errMsg) + return "", "", marshallErrorAsException(statusCode, errMsg) } timestampFieldName := payload.IndexConfig.DocMapping.TimestampField @@ -82,7 +101,7 @@ func getTimestampFieldInfos(index string, qwUrl string, cli *http.Client) (strin if timestampFieldFormat == "undef" { errMsg := fmt.Sprintf("No format found for field: %s", string(timestampFieldName)) qwlog.Error(errMsg) - return timestampFieldName, "", fmt.Errorf(errMsg) + return timestampFieldName, "", marshallErrorAsException(statusCode, errMsg) } qwlog.Info(fmt.Sprintf("Found timestampFieldName = %s, timestampFieldFormat = %s", timestampFieldName, timestampFieldFormat)) diff --git a/src/datasource.ts b/src/datasource.ts index f7547dc..dc09b12 100644 --- a/src/datasource.ts +++ b/src/datasource.ts @@ -51,6 +51,7 @@ import { bucketAggregationConfig } from 'components/QueryEditor/BucketAggregatio import { isBucketAggregationWithField } from 'components/QueryEditor/BucketAggregationsEditor/aggregations'; import ElasticsearchLanguageProvider from 'LanguageProvider'; import { ReactNode } from 'react'; +import { extractJsonPayload } from 'utils'; export const REF_ID_STARTER_LOG_VOLUME = 'log-volume-'; @@ -91,8 +92,18 @@ export class QuickwitDataSource let timestampField = fields.find((field) => field.json_path === timestampFieldName); let timestampFormat = timestampField ? timestampField.field_mapping.output_format || '' : '' let timestampFieldInfos = { 'field': timestampFieldName, 'format': timestampFormat } - console.log("timestampFieldInfos = " + JSON.stringify(timestampFieldInfos)) return timestampFieldInfos + }), + catchError((err) => { + if (!err.data || !err.data.error) { + let err_source = extractJsonPayload(err.data.error) + if(!err_source) { + throw err + } + } + + // the error will be handle in the testDatasource function + return of({'field': '', 'format': ''}) }) ).subscribe(result => { this.timeField = result.field; @@ -143,7 +154,14 @@ export class QuickwitDataSource return of({ status: 'success', message: `Index OK. Time field name OK` }); }), catchError((err) => { - if (err.status === 404) { + if (err.data && err.data.error) { + let err_source = extractJsonPayload(err.data.error) + if (err_source) { + err = err_source + } + } + + if (err.status && err.status === 404) { return of({ status: 'error', message: 'Index does not exists.' }); } else if (err.message) { return of({ status: 'error', message: err.message }); @@ -377,7 +395,7 @@ export class QuickwitDataSource return _map(filteredFields, (field) => { return { text: field.json_path, - value: typeMap[field.field_mapping.type], + value: typeMap[field.field_mapping.type] }; }); }) diff --git a/src/utils.ts b/src/utils.ts index 5b8d940..a6747c3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,6 +13,20 @@ export const describeMetric = (metric: MetricAggregation) => { return `${metricAggregationConfig[metric.type].label} ${metric.field}`; }; +export const extractJsonPayload = (msg: string) => { + const match = msg.match(/{.*}/); + + if (!match) { + return null; + } + + try { + return JSON.parse(match[0]); + } catch (error) { + return null; + } +} + /** * Utility function to clean up aggregations settings objects. * It removes nullish values and empty strings, array and objects