mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugin query API: Handle multiple errors (#63553)
This commit is contained in:
parent
b211ec0a1d
commit
c84cfd2b3f
@ -451,9 +451,15 @@ export interface DataQueryResponse {
|
||||
|
||||
/**
|
||||
* Optionally include error info along with the response data
|
||||
* @deprecated use errors instead -- will be removed in Grafana 10+
|
||||
*/
|
||||
error?: DataQueryError;
|
||||
|
||||
/**
|
||||
* Optionally include multiple errors for different targets
|
||||
*/
|
||||
errors?: DataQueryError[];
|
||||
|
||||
/**
|
||||
* Use this to control which state the response should have
|
||||
* Defaults to LoadingState.Done if state is not defined
|
||||
|
@ -57,6 +57,11 @@ export interface PanelData {
|
||||
timings?: DataQueryTimings;
|
||||
|
||||
/** Any query errors */
|
||||
errors?: DataQueryError[];
|
||||
/**
|
||||
* Single error for legacy reasons
|
||||
* @deprecated use errors instead -- will be removed in Grafana 10+
|
||||
*/
|
||||
error?: DataQueryError;
|
||||
|
||||
/** Contains the range from the request or a shifted time range if a request uses relative time */
|
||||
|
@ -356,6 +356,12 @@ describe('Query Response parser', () => {
|
||||
"refId": "A",
|
||||
}
|
||||
`);
|
||||
expect(res.errors).toEqual([
|
||||
{
|
||||
message: 'Hello Error',
|
||||
refId: 'A',
|
||||
},
|
||||
]);
|
||||
|
||||
const norm = res.data.map((f) => toDataFrameDTO(f));
|
||||
expect(norm).toMatchInlineSnapshot(`
|
||||
|
@ -87,8 +87,13 @@ export function toDataQueryResponse(
|
||||
refId: dr.refId,
|
||||
message: dr.error,
|
||||
};
|
||||
rsp.state = LoadingState.Error;
|
||||
}
|
||||
if (rsp.errors) {
|
||||
rsp.errors.push({ refId: dr.refId, message: dr.error });
|
||||
} else {
|
||||
rsp.errors = [{ refId: dr.refId, message: dr.error }];
|
||||
}
|
||||
rsp.state = LoadingState.Error;
|
||||
}
|
||||
|
||||
if (dr.frames?.length) {
|
||||
|
@ -21,10 +21,12 @@ describe('filterPanelDataToQuery', () => {
|
||||
toDataFrame({ refId: 'B', fields: [{ name: 'B333' }], meta: {} }),
|
||||
toDataFrame({ refId: 'C', fields: [{ name: 'CCCC' }], meta: { requestId: 'sub3' } }),
|
||||
],
|
||||
error: {
|
||||
errors: [
|
||||
{
|
||||
refId: 'B',
|
||||
message: 'Error!!',
|
||||
},
|
||||
],
|
||||
request: makePretendRequest('111', [
|
||||
makePretendRequest('sub1'),
|
||||
makePretendRequest('sub2'),
|
||||
@ -38,6 +40,7 @@ describe('filterPanelDataToQuery', () => {
|
||||
expect(panelData?.series.length).toBe(1);
|
||||
expect(panelData?.series[0].refId).toBe('A');
|
||||
expect(panelData?.error).toBeUndefined();
|
||||
expect(panelData?.errors).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should match the error to the query', () => {
|
||||
@ -45,6 +48,7 @@ describe('filterPanelDataToQuery', () => {
|
||||
expect(panelData?.series.length).toBe(3);
|
||||
expect(panelData?.series[0].refId).toBe('B');
|
||||
expect(panelData?.error!.refId).toBe('B');
|
||||
expect(panelData?.errors![0].refId).toBe('B');
|
||||
});
|
||||
|
||||
it('should include errors when missing data', () => {
|
||||
@ -53,12 +57,14 @@ describe('filterPanelDataToQuery', () => {
|
||||
error: {
|
||||
message: 'Error!!',
|
||||
},
|
||||
errors: [{ message: 'Error!!' }],
|
||||
} as unknown as PanelData;
|
||||
|
||||
const panelData = filterPanelDataToQuery(withError, 'B');
|
||||
expect(panelData).toBeDefined();
|
||||
expect(panelData?.state).toBe(LoadingState.Error);
|
||||
expect(panelData?.error).toBe(withError.error);
|
||||
expect(panelData?.errors).toEqual(withError.errors);
|
||||
});
|
||||
|
||||
it('should set the state to done if the frame has no errors', () => {
|
||||
@ -91,6 +97,7 @@ describe('filterPanelDataToQuery', () => {
|
||||
const panelDataB = filterPanelDataToQuery(withError, 'Q');
|
||||
expect(panelDataB?.series.length).toBe(0);
|
||||
expect(panelDataB?.error?.refId).toBe('Q');
|
||||
expect(panelDataB?.errors![0].refId).toBe('Q');
|
||||
});
|
||||
|
||||
it('should not set the state to done if the frame is loading and has no errors', () => {
|
||||
|
@ -558,7 +558,7 @@ export function filterPanelDataToQuery(data: PanelData, refId: string): PanelDat
|
||||
const series = data.series.filter((series) => series.refId === refId);
|
||||
|
||||
// If there was an error with no data and the panel is not in a loading state, pass it to the QueryEditors
|
||||
if (data.state !== LoadingState.Loading && data.error && !data.series.length) {
|
||||
if (data.state !== LoadingState.Loading && (data.error || data.errors?.length) && !data.series.length) {
|
||||
return {
|
||||
...data,
|
||||
state: LoadingState.Error,
|
||||
@ -567,7 +567,11 @@ export function filterPanelDataToQuery(data: PanelData, refId: string): PanelDat
|
||||
|
||||
// Only say this is an error if the error links to the query
|
||||
let state = data.state;
|
||||
const error = data.error && data.error.refId === refId ? data.error : undefined;
|
||||
let error = data.errors?.find((e) => e.refId === refId);
|
||||
if (!error && data.error) {
|
||||
error = data.error.refId === refId ? data.error : undefined;
|
||||
}
|
||||
|
||||
if (state !== LoadingState.Loading) {
|
||||
if (error) {
|
||||
state = LoadingState.Error;
|
||||
@ -583,6 +587,7 @@ export function filterPanelDataToQuery(data: PanelData, refId: string): PanelDat
|
||||
state,
|
||||
series,
|
||||
error,
|
||||
errors: error ? [error] : undefined,
|
||||
timeRange,
|
||||
};
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ export function processResponsePacket(packet: DataQueryResponse, state: RunningQ
|
||||
|
||||
let loadingState = packet.state || LoadingState.Done;
|
||||
let error: DataQueryError | undefined = undefined;
|
||||
let errors: DataQueryError[] | undefined = undefined;
|
||||
|
||||
const series: DataQueryResponseData[] = [];
|
||||
const annotations: DataQueryResponseData[] = [];
|
||||
@ -60,9 +61,10 @@ export function processResponsePacket(packet: DataQueryResponse, state: RunningQ
|
||||
for (const key in packets) {
|
||||
const packet = packets[key];
|
||||
|
||||
if (packet.error) {
|
||||
if (packet.error || packet.errors?.length) {
|
||||
loadingState = LoadingState.Error;
|
||||
error = packet.error;
|
||||
errors = packet.errors;
|
||||
}
|
||||
|
||||
if (packet.data && packet.data.length) {
|
||||
@ -79,11 +81,12 @@ export function processResponsePacket(packet: DataQueryResponse, state: RunningQ
|
||||
|
||||
const timeRange = getRequestTimeRange(request, loadingState);
|
||||
|
||||
const panelData = {
|
||||
const panelData: PanelData = {
|
||||
state: loadingState,
|
||||
series,
|
||||
annotations,
|
||||
error,
|
||||
errors,
|
||||
request,
|
||||
timeRange,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user