mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
fix: Remove the onRenderError prop and add an ErrorBoundary component
This commit is contained in:
parent
bcb94cc0ec
commit
f428db282c
@ -9,7 +9,6 @@ export interface PanelProps<T = any> {
|
||||
renderCounter: number;
|
||||
width: number;
|
||||
height: number;
|
||||
onRenderError: () => void;
|
||||
}
|
||||
|
||||
export interface PanelOptionsProps<T = any> {
|
||||
|
@ -13,7 +13,6 @@ interface GraphProps {
|
||||
showBars?: boolean;
|
||||
width: number;
|
||||
height: number;
|
||||
onRenderError: () => void;
|
||||
}
|
||||
|
||||
export class Graph extends PureComponent<GraphProps> {
|
||||
@ -38,7 +37,7 @@ export class Graph extends PureComponent<GraphProps> {
|
||||
return;
|
||||
}
|
||||
|
||||
const { width, timeSeries, timeRange, showLines, showBars, showPoints, onRenderError } = this.props;
|
||||
const { width, timeSeries, timeRange, showLines, showBars, showPoints } = this.props;
|
||||
|
||||
if (!width) {
|
||||
return;
|
||||
@ -99,7 +98,7 @@ export class Graph extends PureComponent<GraphProps> {
|
||||
$.plot(this.element, timeSeries, flotOptions);
|
||||
} catch (err) {
|
||||
console.log('Graph rendering error', err, flotOptions, timeSeries);
|
||||
onRenderError();
|
||||
throw new Error('Error rendering panel');
|
||||
}
|
||||
}
|
||||
|
||||
|
47
public/app/core/components/ErrorBoundary/ErrorBoundary.tsx
Normal file
47
public/app/core/components/ErrorBoundary/ErrorBoundary.tsx
Normal 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;
|
@ -1,6 +1,7 @@
|
||||
// Library
|
||||
import React, { Component } from 'react';
|
||||
import Tooltip from 'app/core/components/Tooltip/Tooltip';
|
||||
import ErrorBoundary from 'app/core/components/ErrorBoundary/ErrorBoundary';
|
||||
|
||||
// Services
|
||||
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 { Themes } from 'app/core/components/Tooltip/Popper';
|
||||
|
||||
const DEFAULT_PLUGIN_ERROR = 'Error in plugin';
|
||||
|
||||
interface RenderProps {
|
||||
loading: LoadingState;
|
||||
timeSeries: TimeSeries[];
|
||||
onRenderError: () => void;
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
@ -147,10 +149,6 @@ export class DataPanel extends Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
onRenderError = () => {
|
||||
this.onError('Error rendering panel');
|
||||
}
|
||||
|
||||
render() {
|
||||
const { queries } = this.props;
|
||||
const { response, loading, isFirstLoad } = this.state;
|
||||
@ -172,13 +170,24 @@ export class DataPanel extends Component<Props, State> {
|
||||
return (
|
||||
<>
|
||||
{this.renderLoadingStates()}
|
||||
<ErrorBoundary>
|
||||
{({error, errorInfo}) => {
|
||||
if (errorInfo) {
|
||||
this.onError(error.message || DEFAULT_PLUGIN_ERROR);
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{this.props.children({
|
||||
timeSeries,
|
||||
loading,
|
||||
onRenderError: this.onRenderError
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</ErrorBoundary>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private renderLoadingStates(): JSX.Element {
|
||||
|
@ -114,7 +114,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
||||
widthPixels={width}
|
||||
refreshCounter={refreshCounter}
|
||||
>
|
||||
{({ loading, timeSeries, onRenderError }) => {
|
||||
{({ loading, timeSeries }) => {
|
||||
return (
|
||||
<div className="panel-content">
|
||||
<PanelComponent
|
||||
@ -125,7 +125,6 @@ export class PanelChrome extends PureComponent<Props, State> {
|
||||
width={width}
|
||||
height={height - PANEL_HEADER_HEIGHT}
|
||||
renderCounter={renderCounter}
|
||||
onRenderError={onRenderError}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -10,12 +10,12 @@ import { Options } from './types';
|
||||
interface Props extends PanelProps<Options> {}
|
||||
|
||||
export class GraphPanel extends PureComponent<Props> {
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { timeSeries, timeRange, width, height, onRenderError } = this.props;
|
||||
const { timeSeries, timeRange, width, height } = this.props;
|
||||
const { showLines, showBars, showPoints } = this.props.options;
|
||||
|
||||
const vmSeries = processTimeSeries({
|
||||
@ -33,7 +33,6 @@ export class GraphPanel extends PureComponent<Props> {
|
||||
showBars={showBars}
|
||||
width={width}
|
||||
height={height}
|
||||
onRenderError={onRenderError}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user