fix: Remove the onRenderError prop and add an ErrorBoundary component

This commit is contained in:
Johannes Schill 2019-01-08 13:32:08 +01:00
parent bcb94cc0ec
commit f428db282c
6 changed files with 71 additions and 19 deletions

View File

@ -9,7 +9,6 @@ export interface PanelProps<T = any> {
renderCounter: number; renderCounter: number;
width: number; width: number;
height: number; height: number;
onRenderError: () => void;
} }
export interface PanelOptionsProps<T = any> { export interface PanelOptionsProps<T = any> {

View File

@ -13,7 +13,6 @@ interface GraphProps {
showBars?: boolean; showBars?: boolean;
width: number; width: number;
height: number; height: number;
onRenderError: () => void;
} }
export class Graph extends PureComponent<GraphProps> { export class Graph extends PureComponent<GraphProps> {
@ -38,7 +37,7 @@ export class Graph extends PureComponent<GraphProps> {
return; return;
} }
const { width, timeSeries, timeRange, showLines, showBars, showPoints, onRenderError } = this.props; const { width, timeSeries, timeRange, showLines, showBars, showPoints } = this.props;
if (!width) { if (!width) {
return; return;
@ -99,7 +98,7 @@ export class Graph extends PureComponent<GraphProps> {
$.plot(this.element, timeSeries, flotOptions); $.plot(this.element, timeSeries, flotOptions);
} catch (err) { } catch (err) {
console.log('Graph rendering error', err, flotOptions, timeSeries); console.log('Graph rendering error', err, flotOptions, timeSeries);
onRenderError(); throw new Error('Error rendering panel');
} }
} }

View File

@ -0,0 +1,47 @@
import React, { Component } from 'react';
interface ErrorInfo {
componentStack: string;
}
interface RenderProps {
error: Error;
errorInfo: ErrorInfo;
}
interface Props {
children: (r: RenderProps) => JSX.Element;
}
interface State {
error: Error;
errorInfo: ErrorInfo;
}
class ErrorBoundary extends Component<Props, State> {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
this.setState({
error: error,
errorInfo: errorInfo
});
}
render() {
const { error, errorInfo } = this.state;
return (
<>
{this.props.children({
error,
errorInfo,
})}
</>
);
}
}
export default ErrorBoundary;

View File

@ -1,6 +1,7 @@
// Library // Library
import React, { Component } from 'react'; import React, { Component } from 'react';
import Tooltip from 'app/core/components/Tooltip/Tooltip'; import Tooltip from 'app/core/components/Tooltip/Tooltip';
import ErrorBoundary from 'app/core/components/ErrorBoundary/ErrorBoundary';
// Services // Services
import { getDatasourceSrv, DatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getDatasourceSrv, DatasourceSrv } from 'app/features/plugins/datasource_srv';
@ -13,10 +14,11 @@ import { DataQueryOptions, DataQueryResponse } from 'app/types';
import { TimeRange, TimeSeries, LoadingState } from '@grafana/ui'; import { TimeRange, TimeSeries, LoadingState } from '@grafana/ui';
import { Themes } from 'app/core/components/Tooltip/Popper'; import { Themes } from 'app/core/components/Tooltip/Popper';
const DEFAULT_PLUGIN_ERROR = 'Error in plugin';
interface RenderProps { interface RenderProps {
loading: LoadingState; loading: LoadingState;
timeSeries: TimeSeries[]; timeSeries: TimeSeries[];
onRenderError: () => void;
} }
export interface Props { export interface Props {
@ -147,10 +149,6 @@ export class DataPanel extends Component<Props, State> {
} }
} }
onRenderError = () => {
this.onError('Error rendering panel');
}
render() { render() {
const { queries } = this.props; const { queries } = this.props;
const { response, loading, isFirstLoad } = this.state; const { response, loading, isFirstLoad } = this.state;
@ -172,11 +170,22 @@ export class DataPanel extends Component<Props, State> {
return ( return (
<> <>
{this.renderLoadingStates()} {this.renderLoadingStates()}
{this.props.children({ <ErrorBoundary>
timeSeries, {({error, errorInfo}) => {
loading, if (errorInfo) {
onRenderError: this.onRenderError this.onError(error.message || DEFAULT_PLUGIN_ERROR);
})} return null;
}
return (
<>
{this.props.children({
timeSeries,
loading,
})}
</>
);
}}
</ErrorBoundary>
</> </>
); );
} }

View File

@ -114,7 +114,7 @@ export class PanelChrome extends PureComponent<Props, State> {
widthPixels={width} widthPixels={width}
refreshCounter={refreshCounter} refreshCounter={refreshCounter}
> >
{({ loading, timeSeries, onRenderError }) => { {({ loading, timeSeries }) => {
return ( return (
<div className="panel-content"> <div className="panel-content">
<PanelComponent <PanelComponent
@ -125,7 +125,6 @@ export class PanelChrome extends PureComponent<Props, State> {
width={width} width={width}
height={height - PANEL_HEADER_HEIGHT} height={height - PANEL_HEADER_HEIGHT}
renderCounter={renderCounter} renderCounter={renderCounter}
onRenderError={onRenderError}
/> />
</div> </div>
); );

View File

@ -10,12 +10,12 @@ import { Options } from './types';
interface Props extends PanelProps<Options> {} interface Props extends PanelProps<Options> {}
export class GraphPanel extends PureComponent<Props> { export class GraphPanel extends PureComponent<Props> {
constructor(props) { constructor(props: Props) {
super(props); super(props);
} }
render() { render() {
const { timeSeries, timeRange, width, height, onRenderError } = this.props; const { timeSeries, timeRange, width, height } = this.props;
const { showLines, showBars, showPoints } = this.props.options; const { showLines, showBars, showPoints } = this.props.options;
const vmSeries = processTimeSeries({ const vmSeries = processTimeSeries({
@ -33,7 +33,6 @@ export class GraphPanel extends PureComponent<Props> {
showBars={showBars} showBars={showBars}
width={width} width={width}
height={height} height={height}
onRenderError={onRenderError}
/> />
); );
} }