Przeglądaj źródła

bubble error from datapanel to panelchrome

Peter Holmberg 6 lat temu
rodzic
commit
530a370379

+ 15 - 61
public/app/features/dashboard/dashgrid/DataPanel.tsx

@@ -1,8 +1,6 @@
 // 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,
+    });
   }
 }

+ 49 - 27
public/app/features/dashboard/dashgrid/PanelChrome.tsx

@@ -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>
           );
         }}