Commit 530a3703 by Peter Holmberg

bubble error from datapanel to panelchrome

parent 1db5d86b
// Library
import React, { Component } from 'react';
import { Tooltip } from '@grafana/ui';
import ErrorBoundary from 'app/core/components/ErrorBoundary/ErrorBoundary';
// Services
import { DatasourceSrv, getDatasourceSrv } from 'app/features/plugins/datasource_srv';
// Utils
......@@ -18,8 +16,6 @@ import {
TimeSeries,
} from '@grafana/ui';
const DEFAULT_PLUGIN_ERROR = 'Error in plugin';
interface RenderProps {
loading: LoadingState;
panelData: PanelData;
......@@ -38,12 +34,12 @@ export interface Props {
maxDataPoints?: number;
children: (r: RenderProps) => JSX.Element;
onDataResponse?: (data: DataQueryResponse) => void;
onError?: (errorMessage: string) => void;
}
export interface State {
isFirstLoad: boolean;
loading: LoadingState;
errorMessage: string;
response: DataQueryResponse;
}
......@@ -62,7 +58,6 @@ export class DataPanel extends Component<Props, State> {
this.state = {
loading: LoadingState.NotStarted,
errorMessage: '',
response: {
data: [],
},
......@@ -112,7 +107,7 @@ export class DataPanel extends Component<Props, State> {
return;
}
this.setState({ loading: LoadingState.Loading, errorMessage: '' });
this.setState({ loading: LoadingState.Loading });
try {
const ds = await this.dataSourceSrv.get(datasource);
......@@ -152,19 +147,13 @@ export class DataPanel extends Component<Props, State> {
});
} catch (err) {
console.log('Loading error', err);
this.onError('Request Error');
this.setState({ isFirstLoad: false });
this.props.onError('Request Error');
}
};
onError = (errorMessage: string) => {
if (this.state.loading !== LoadingState.Error || this.state.errorMessage !== errorMessage) {
this.setState({
loading: LoadingState.Error,
isFirstLoad: false,
errorMessage: errorMessage,
});
}
};
// error som callback eller renderprop?
// ta bort error, bubbla till panelchrome
getPanelData = () => {
const { response } = this.state;
......@@ -189,59 +178,24 @@ export class DataPanel extends Component<Props, State> {
const panelData = this.getPanelData();
if (isFirstLoad && loading === LoadingState.Loading) {
return this.renderLoadingStates();
}
if (!queries.length) {
return (
<div className="panel-empty">
<p>Add a query to get some data!</p>
<div className="panel-loading">
<i className="fa fa-spinner fa-spin" />
</div>
);
}
return (
<>
{this.renderLoadingStates()}
<ErrorBoundary>
{({ error, errorInfo }) => {
if (errorInfo) {
this.onError(error.message || DEFAULT_PLUGIN_ERROR);
return null;
}
return (
<>
{this.props.children({
loading,
panelData,
})}
</>
);
}}
</ErrorBoundary>
</>
);
}
private renderLoadingStates(): JSX.Element {
const { loading, errorMessage } = this.state;
if (loading === LoadingState.Loading) {
if (!queries.length) {
return (
<div className="panel-loading">
<i className="fa fa-spinner fa-spin" />
<div className="panel-empty">
<p>Add a query to get some data!</p>
</div>
);
} else if (loading === LoadingState.Error) {
return (
<Tooltip content={errorMessage} placement="bottom-start" theme="error">
<div className="panel-info-corner panel-info-corner--error">
<i className="fa" />
<span className="panel-info-corner-inner" />
</div>
</Tooltip>
);
}
return null;
return this.props.children({
loading,
panelData,
});
}
}
......@@ -8,6 +8,7 @@ import { getTimeSrv, TimeSrv } from '../services/TimeSrv';
// Components
import { PanelHeader } from './PanelHeader/PanelHeader';
import { DataPanel } from './DataPanel';
import ErrorBoundary from '../../../core/components/ErrorBoundary/ErrorBoundary';
// Utils
import { applyPanelTimeOverrides, snapshotDataToPanelData } from 'app/features/dashboard/utils/panel';
......@@ -17,11 +18,12 @@ import { profiler } from 'app/core/profiler';
// Types
import { DashboardModel, PanelModel } from '../state';
import { PanelPlugin } from 'app/types';
import { TimeRange, LoadingState, PanelData } from '@grafana/ui';
import { DataQueryResponse, TimeRange, LoadingState, PanelData } from '@grafana/ui';
import variables from 'sass/_variables.scss';
import templateSrv from 'app/features/templating/template_srv';
import { DataQueryResponse } from '@grafana/ui/src';
const DEFAULT_PLUGIN_ERROR = 'Error in plugin';
export interface Props {
panel: PanelModel;
......@@ -34,6 +36,8 @@ export interface State {
renderCounter: number;
timeInfo?: string;
timeRange?: TimeRange;
loading: LoadingState;
errorMessage: string;
}
export class PanelChrome extends PureComponent<Props, State> {
......@@ -45,6 +49,8 @@ export class PanelChrome extends PureComponent<Props, State> {
this.state = {
refreshCounter: 0,
renderCounter: 0,
loading: LoadingState.NotStarted,
errorMessage: '',
};
}
......@@ -127,33 +133,41 @@ export class PanelChrome extends PureComponent<Props, State> {
const { datasource, targets } = panel;
return (
<>
{panel.snapshotData && panel.snapshotData.length > 0 ? (
this.renderPanelPlugin(LoadingState.Done, snapshotDataToPanelData(panel), width, height)
) : (
<>
{plugin.noQueries ?
this.renderPanelPlugin(LoadingState.Done, null, width, height)
: (
<DataPanel
datasource={datasource}
queries={targets}
timeRange={timeRange}
isVisible={this.isVisible}
widthPixels={width}
refreshCounter={refreshCounter}
onDataResponse={this.onDataResponse}
>
{({ loading, panelData }) => {
return this.renderPanelPlugin(loading, panelData, width, height);
}}
</DataPanel>
)}
</>
)}
{panel.snapshotData && panel.snapshotData.length > 0 ? (
this.renderPanelPlugin(LoadingState.Done, snapshotDataToPanelData(panel), width, height)
) : (
<>
{plugin.noQueries ? (
this.renderPanelPlugin(LoadingState.Done, null, width, height)
) : (
<DataPanel
datasource={datasource}
queries={targets}
timeRange={timeRange}
isVisible={this.isVisible}
widthPixels={width}
refreshCounter={refreshCounter}
onDataResponse={this.onDataResponse}
>
{({ loading, panelData }) => {
return this.renderPanelPlugin(loading, panelData, width, height);
}}
</DataPanel>
)}
</>
)}
</>
);
}
};
onError = (errorMessage: string) => {
if (this.state.loading !== LoadingState.Error || this.state.errorMessage !== errorMessage) {
this.setState({
loading: LoadingState.Error,
errorMessage: errorMessage,
});
}
};
render() {
const { dashboard, panel } = this.props;
......@@ -179,7 +193,15 @@ export class PanelChrome extends PureComponent<Props, State> {
scopedVars={panel.scopedVars}
links={panel.links}
/>
{this.renderHelper(width, height)}
<ErrorBoundary>
{({ error, errorInfo }) => {
if (errorInfo) {
this.onError(error.message || DEFAULT_PLUGIN_ERROR);
return null;
}
return this.renderHelper(width, height);
}}
</ErrorBoundary>
</div>
);
}}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment