From 6619cc4b816e6778b68a46ba6c1404f7af845bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 16 Jul 2020 07:45:26 +0200 Subject: [PATCH] Loki: Fix error handling (#26291) * Loki: Fix error handling * Keep custom error processing for escaping * Fix failing test Co-authored-by: Ivana --- .../datasource/loki/datasource.test.ts | 6 ++- .../app/plugins/datasource/loki/datasource.ts | 49 +++++-------------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/public/app/plugins/datasource/loki/datasource.test.ts b/public/app/plugins/datasource/loki/datasource.test.ts index bcae7537d0e..740cdef65c5 100644 --- a/public/app/plugins/datasource/loki/datasource.test.ts +++ b/public/app/plugins/datasource/loki/datasource.test.ts @@ -176,7 +176,9 @@ describe('LokiDatasource', () => { datasourceRequestMock.mockImplementation( jest.fn().mockReturnValueOnce( Promise.reject({ - data: 'parse error at line 1, col 6: invalid char escape', + data: { + message: 'parse error at line 1, col 6: invalid char escape', + }, status: 400, statusText: 'Bad Request', }) @@ -189,7 +191,7 @@ describe('LokiDatasource', () => { try { await ds.query(options).toPromise(); } catch (err) { - expect(err.message).toBe( + expect(err.data.message).toBe( 'Error: parse error at line 1, col 6: invalid char escape. Make sure that all special characters are escaped with \\. For more information on escaping of special characters visit LogQL documentation at https://github.com/grafana/loki/blob/master/docs/logql.md.' ); } diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 0f4132c09f8..168314e7382 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -1,14 +1,14 @@ // Libraries -import { isEmpty, map as lodashMap } from 'lodash'; +import { isEmpty, map as lodashMap, cloneDeep } from 'lodash'; import { Observable, from, merge, of } from 'rxjs'; -import { map, filter, catchError, switchMap } from 'rxjs/operators'; +import { map, catchError, switchMap } from 'rxjs/operators'; // Services & Utils import { DataFrame, dateMath, FieldCache, QueryResultMeta } from '@grafana/data'; -import { getBackendSrv, BackendSrvRequest } from '@grafana/runtime'; +import { getBackendSrv, BackendSrvRequest, FetchError } from '@grafana/runtime'; import { addLabelToQuery } from 'app/plugins/datasource/prometheus/add_label_to_query'; import { TemplateSrv } from 'app/features/templating/template_srv'; -import { safeStringifyValue, convertToWebSocketUrl } from 'app/core/utils/explore'; +import { convertToWebSocketUrl } from 'app/core/utils/explore'; import { lokiResultsToTableModel, processRangeQueryResponse, lokiStreamResultToDataFrame } from './result_transformer'; import { getHighlighterExpressionsFromQuery } from './query_utils'; @@ -120,8 +120,6 @@ export class LokiDatasource extends DataSourceApi { }; return this._request(INSTANT_QUERY_ENDPOINT, query).pipe( - catchError((err: any) => this.throwUnless(err, err.cancelled, target)), - filter((response: any) => (response.cancelled ? false : true)), map((response: { data: LokiResponse }) => { if (response.data.data.resultType === LokiResultType.Stream) { return { @@ -200,8 +198,7 @@ export class LokiDatasource extends DataSourceApi { } const query = this.createRangeQuery(target, queryOptions); return this._request(RANGE_QUERY_ENDPOINT, query).pipe( - catchError((err: any) => this.throwUnless(err, err.cancelled || err.status === 404, target)), - filter((response: any) => (response.cancelled ? false : true)), + catchError((err: any) => this.throwUnless(err, err.status === 404, target)), switchMap((response: { data: LokiResponse; status: number }) => processRangeQueryResponse( response.data, @@ -498,42 +495,22 @@ export class LokiDatasource extends DataSourceApi { return (row && row.searchWords && row.searchWords.length > 0) === true; } - throwUnless = (err: any, condition: boolean, target: LokiQuery) => { + throwUnless(err: FetchError, condition: boolean, target: LokiQuery) { if (condition) { return of(err); } - const error: DataQueryError = this.processError(err, target); + const error = this.processError(err, target); throw error; - }; + } - processError = (err: any, target: LokiQuery): DataQueryError => { - const error: DataQueryError = { - message: (err && err.statusText) || 'Unknown error during query transaction. Please check JS console logs.', - refId: target.refId, - }; - - if (err.data) { - if (typeof err.data === 'string') { - if (err.data.includes('escape') && target.expr.includes('\\')) { - error.message = `Error: ${err.data}. Make sure that all special characters are escaped with \\. For more information on escaping of special characters visit LogQL documentation at https://github.com/grafana/loki/blob/master/docs/logql.md.`; - } else { - error.message = err.data; - } - } else if (err.data.error) { - error.message = safeStringifyValue(err.data.error); - } - } else if (err.message) { - error.message = err.message; - } else if (typeof err === 'string') { - error.message = err; + processError(err: FetchError, target: LokiQuery) { + let error = cloneDeep(err); + if (err.data.message.includes('escape') && target.expr.includes('\\')) { + error.data.message = `Error: ${err.data.message}. Make sure that all special characters are escaped with \\. For more information on escaping of special characters visit LogQL documentation at https://github.com/grafana/loki/blob/master/docs/logql.md.`; } - - error.status = err.status; - error.statusText = err.statusText; - return error; - }; + } adjustInterval(interval: number, range: number) { // Loki will drop queries that might return more than 11000 data points.