Azure Monitor: Improved error messages for variable queries (#43213)

pull/44121/head
Erik Sundell 3 years ago committed by GitHub
parent 715166baf3
commit 5ae5a2e0d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/errors.ts
  2. 8
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.test.tsx
  3. 7
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/VariableEditor/VariableEditor.tsx
  4. 30
      public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.test.ts
  5. 5
      public/app/plugins/datasource/grafana-azure-monitor-datasource/variables.ts

@ -20,3 +20,15 @@ export function invalidNamespaceError() {
},
};
}
export function invalidSubscriptionError() {
return {
status: 400,
data: {
error: {
code: 'InvalidSubscriptionId',
message: "The provided subscription identifier 'abc' is malformed or invalid.",
},
},
};
}

@ -6,8 +6,6 @@ import createMockDatasource from '../../__mocks__/datasource';
import { AzureMonitorQuery, AzureQueryType } from '../../types';
import { select } from 'react-select-event';
import * as ui from '@grafana/ui';
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash';
// Have to mock CodeEditor because it doesnt seem to work in tests???
jest.mock('@grafana/ui', () => ({
@ -17,11 +15,6 @@ jest.mock('@grafana/ui', () => ({
},
}));
jest.mock('lodash', () => ({
...jest.requireActual<typeof _>('lodash'),
debounce: jest.fn((fn: unknown) => fn),
}));
describe('VariableEditor:', () => {
it('can select a query type', async () => {
const onChange = jest.fn();
@ -141,7 +134,6 @@ describe('VariableEditor:', () => {
} as AzureMonitorQuery,
onChange: jest.fn(),
datasource: createMockDatasource(),
debounceTime: 1,
};
render(<VariableEditor {...props} />);
await waitFor(() => screen.queryByText('Grafana template variable function'));

@ -1,13 +1,12 @@
import { SelectableValue } from '@grafana/data';
import { Alert, InlineField, Input, Select } from '@grafana/ui';
import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react';
import React, { ChangeEvent, useCallback, useEffect, useState } from 'react';
import { AzureMonitorQuery, AzureQueryType } from '../../types';
import LogsQueryEditor from '../LogsQueryEditor';
import DataSource from '../../datasource';
import useLastError from '../../utils/useLastError';
import { Space } from '../Space';
import { migrateStringQueriesToObjectQueries } from '../../grafanaTemplateVariableFns';
import { debounce } from 'lodash';
const AZURE_QUERY_VARIABLE_TYPE_OPTIONS = [
{ label: 'Grafana Query Function', value: AzureQueryType.GrafanaTemplateVariableFn },
@ -46,18 +45,18 @@ const GrafanaTemplateVariableFnInput = ({
},
[datasource, query, updateQuery]
);
const debouncedRunQuery = useMemo(() => debounce(onRunQuery, 500), [onRunQuery]);
const onChange = (event: ChangeEvent<HTMLInputElement>) => {
setInputVal(event.target.value);
debouncedRunQuery(event.target.value);
};
return (
<InlineField label="Grafana template variable function">
<Input
placeholder={'type a grafana template variable function, ex: Subscriptions()'}
value={inputVal}
onChange={onChange}
onBlur={() => onRunQuery(inputVal)}
/>
</InlineField>
);

@ -3,6 +3,7 @@ import { from } from 'rxjs';
import { AzureMonitorQuery, AzureQueryType } from './types';
import { VariableSupport } from './variables';
import createMockDatasource from './__mocks__/datasource';
import { invalidSubscriptionError } from './__mocks__/errors';
jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as object),
@ -499,4 +500,33 @@ describe('VariableSupport', () => {
done();
});
});
it('should handle http error', (done) => {
const error = invalidSubscriptionError();
const variableSupport = new VariableSupport(
createMockDatasource({
azureLogAnalyticsDatasource: {
defaultSubscriptionId: 'defaultSubscriptionId',
},
getResourceGroups: jest.fn().mockRejectedValue(error),
})
);
const mockRequest = {
targets: [
{
refId: 'A',
queryType: AzureQueryType.GrafanaTemplateVariableFn,
grafanaTemplateVariableFn: {
kind: 'ResourceGroupsQuery',
rawQuery: 'ResourceGroups()',
},
} as AzureMonitorQuery,
],
} as DataQueryRequest<AzureMonitorQuery>;
const observables = variableSupport.query(mockRequest);
observables.subscribe((result: DataQueryResponseData) => {
expect(result.error?.message).toBe(error.data.error.message);
done();
});
});
});

@ -12,6 +12,7 @@ import { AzureQueryType, AzureMonitorQuery } from './types';
import { getTemplateSrv } from '@grafana/runtime';
import { migrateStringQueriesToObjectQueries } from './grafanaTemplateVariableFns';
import { GrafanaTemplateVariableQuery } from './types/templateVariables';
import messageFromError from './utils/messageFromError';
export class VariableSupport extends CustomVariableSupport<DataSource, AzureMonitorQuery> {
constructor(private readonly datasource: DataSource) {
super();
@ -26,10 +27,14 @@ export class VariableSupport extends CustomVariableSupport<DataSource, AzureMoni
const queryObj = await migrateStringQueriesToObjectQueries(request.targets[0], { datasource: this.datasource });
if (queryObj.queryType === AzureQueryType.GrafanaTemplateVariableFn && queryObj.grafanaTemplateVariableFn) {
try {
const templateVariablesResults = await this.callGrafanaTemplateVariableFn(queryObj.grafanaTemplateVariableFn);
return {
data: templateVariablesResults ? [toDataFrame(templateVariablesResults)] : [],
};
} catch (err) {
return { data: [], error: { message: messageFromError(err) } };
}
}
request.targets[0] = queryObj;
return lastValueFrom(this.datasource.query(request));

Loading…
Cancel
Save