Inspector: Show transformation query errors (#73344)

This commit is contained in:
Ryan McKinley 2023-09-20 09:09:51 -07:00 committed by GitHub
parent 9def0d2305
commit a1250632c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 19 deletions

View File

@ -1,7 +1,16 @@
import { isEmpty } from 'lodash';
import React, { useState } from 'react';
import { CoreApp, DataSourceApi, formattedValueToString, getValueFormat, PanelData, PanelPlugin } from '@grafana/data';
import {
CoreApp,
DataSourceApi,
formattedValueToString,
getValueFormat,
PanelData,
PanelPlugin,
LoadingState,
DataQueryError,
} from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { Drawer, Tab, TabsBar } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
@ -51,10 +60,7 @@ export const InspectContent = ({
return null;
}
let errors = data?.errors;
if (!errors?.length && data?.error) {
errors = [data.error];
}
let errors = getErrors(data);
// Validate that the active tab is actually valid and allowed
let activeTab = currentTab;
@ -114,6 +120,22 @@ export const InspectContent = ({
);
};
// This will combine
function getErrors(data: PanelData | undefined): DataQueryError[] {
let errors = data?.errors ?? [];
if (data?.error && !errors.includes(data.error)) {
errors = [data.error, ...errors];
}
if (!errors.length && data?.state === LoadingState.Error) {
return [
{
message: 'Error loading data',
},
];
}
return errors;
}
function formatStats(data: PanelData) {
const { request } = data;

View File

@ -28,16 +28,16 @@ export interface ConnectedProps {
export type Props = OwnProps & ConnectedProps;
const PanelInspectorUnconnected = ({ panel, dashboard, plugin }: Props) => {
const location = useLocation();
const defaultTab = new URLSearchParams(location.search).get('inspectTab') as InspectTab;
const [dataOptions, setDataOptions] = useState<GetDataOptions>({
withTransforms: false,
withTransforms: defaultTab === InspectTab.Error,
withFieldConfig: true,
});
const location = useLocation();
const { data, isLoading, error } = usePanelLatestData(panel, dataOptions, false);
const { data, isLoading, hasError } = usePanelLatestData(panel, dataOptions, true);
const metaDs = useDatasourceMetadata(data);
const tabs = useInspectTabs(panel, dashboard, plugin, error, metaDs);
const defaultTab = new URLSearchParams(location.search).get('inspectTab') as InspectTab;
const tabs = useInspectTabs(panel, dashboard, plugin, hasError, metaDs);
const onClose = () => {
locationService.partial({

View File

@ -1,7 +1,7 @@
import { useMemo } from 'react';
import useAsync from 'react-use/lib/useAsync';
import { DataQueryError, DataSourceApi, PanelData, PanelPlugin } from '@grafana/data';
import { DataSourceApi, PanelData, PanelPlugin } from '@grafana/data';
import { getDataSourceSrv } from '@grafana/runtime';
import { t } from 'app/core/internationalization';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
@ -42,7 +42,7 @@ export const useInspectTabs = (
panel: PanelModel,
dashboard: DashboardModel,
plugin: PanelPlugin | undefined | null,
error?: DataQueryError,
hasError?: boolean,
metaDs?: DataSourceApi
) => {
return useMemo(() => {
@ -58,7 +58,7 @@ export const useInspectTabs = (
tabs.push({ label: t('dashboard.inspect.json-tab', 'JSON'), value: InspectTab.JSON });
if (error && error.message) {
if (hasError) {
tabs.push({ label: t('dashboard.inspect.error-tab', 'Error'), value: InspectTab.Error });
}
@ -66,5 +66,5 @@ export const useInspectTabs = (
tabs.push({ label: t('dashboard.inspect.query-tab', 'Query'), value: InspectTab.Query });
}
return tabs;
}, [plugin, metaDs, dashboard, error]);
}, [plugin, metaDs, dashboard, hasError]);
};

View File

@ -1,14 +1,14 @@
import { useEffect, useRef, useState } from 'react';
import { Unsubscribable } from 'rxjs';
import { DataQueryError, LoadingState, PanelData } from '@grafana/data';
import { LoadingState, PanelData } from '@grafana/data';
import { GetDataOptions } from '../../../query/state/PanelQueryRunner';
import { PanelModel } from '../../state';
interface UsePanelLatestData {
data?: PanelData;
error?: DataQueryError;
hasError: boolean;
isLoading: boolean;
hasSeries: boolean;
}
@ -63,8 +63,10 @@ export const usePanelLatestData = (
return {
data: latestData,
error: latestData && latestData.error,
isLoading: latestData?.state === LoadingState.Loading,
hasSeries: latestData ? !!latestData.series : false,
hasError: Boolean(
latestData && (latestData.error || latestData?.errors?.length || latestData.state === LoadingState.Error)
),
};
};

View File

@ -67,7 +67,7 @@ export const InspectErrorTab = ({ errors }: InspectErrorTabProps) => {
return (
<>
{errors.map((error, index) => (
<Alert title={error.refId || `Query ${index + 1}`} severity="error" key={index}>
<Alert title={error.refId || `Error ${index + 1}`} severity="error" key={index}>
{renderError(error)}
</Alert>
))}

View File

@ -225,7 +225,7 @@ export class PanelQueryRunner {
return of({
...data,
state: LoadingState.Error,
error: toDataQueryError(err),
errors: [toDataQueryError(err)],
});
})
);