Add Error Boundary for

- the Page component
- the Main component
This commit is contained in:
Mohamed Karray
2019-03-13 21:41:08 +01:00
parent 35c84c929a
commit 13e7ae24bd
5 changed files with 124 additions and 125 deletions

View File

@@ -0,0 +1,28 @@
// @flow
import React from "react";
import ErrorNotification from "./ErrorNotification";
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error, errorInfo) {
// Catch errors in any components below and re-render with error message
this.setState({
error: error,
errorInfo: errorInfo
});
}
render() {
if (this.state.errorInfo) {
return (
<ErrorNotification error={this.state.error} />
);
}
return this.props.children;
}
}
export default ErrorBoundary;

View File

@@ -1,32 +0,0 @@
//@flow
import * as React from "react";
class PageErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
/**
* This lifecycle is invoked after an error has been thrown by a descendant component.
* It receives the error that was thrown as a parameter and should return a value to update state.
* @param error
* @returns {{hasError: boolean}}
*/
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default PageErrorBoundary;

View File

@@ -25,6 +25,7 @@ export { default as Tooltip } from "./Tooltip";
export { getPageFromMatch } from "./urls"; export { getPageFromMatch } from "./urls";
export { default as Autocomplete} from "./Autocomplete"; export { default as Autocomplete} from "./Autocomplete";
export { default as BranchSelector } from "./BranchSelector"; export { default as BranchSelector } from "./BranchSelector";
export { default as ErrorBoundary } from "./ErrorBoundary";
export { apiClient } from "./apiclient.js"; export { apiClient } from "./apiclient.js";
export * from "./errors"; export * from "./errors";

View File

@@ -7,7 +7,7 @@ import Subtitle from "./Subtitle";
import injectSheet from "react-jss"; import injectSheet from "react-jss";
import classNames from "classnames"; import classNames from "classnames";
import PageActions from "./PageActions"; import PageActions from "./PageActions";
import PageErrorBoundary from "../errorboundary/PageErrorBoundary"; import ErrorBoundary from "../ErrorBoundary";
type Props = { type Props = {
title?: string, title?: string,
@@ -32,7 +32,7 @@ class Page extends React.Component<Props> {
render() { render() {
const { error } = this.props; const { error } = this.props;
return ( return (
<PageErrorBoundary> <ErrorBoundary>
<section className="section"> <section className="section">
<div className="container"> <div className="container">
{this.renderPageHeader()} {this.renderPageHeader()}
@@ -40,7 +40,7 @@ class Page extends React.Component<Props> {
{this.renderContent()} {this.renderContent()}
</div> </div>
</section> </section>
</PageErrorBoundary> </ErrorBoundary>
); );
} }

View File

@@ -9,7 +9,7 @@ import Users from "../users/containers/Users";
import Login from "../containers/Login"; import Login from "../containers/Login";
import Logout from "../containers/Logout"; import Logout from "../containers/Logout";
import { ProtectedRoute } from "@scm-manager/ui-components"; import {ErrorBoundary, ProtectedRoute} from "@scm-manager/ui-components";
import {binder, ExtensionPoint } from "@scm-manager/ui-extensions"; import {binder, ExtensionPoint } from "@scm-manager/ui-extensions";
import AddUser from "../users/containers/AddUser"; import AddUser from "../users/containers/AddUser";
@@ -38,97 +38,99 @@ class Main extends React.Component<Props> {
url = redirectUrlFactory(this.props); url = redirectUrlFactory(this.props);
} }
return ( return (
<div className="main"> <ErrorBoundary>
<Switch> <div className="main">
<Redirect exact from="/" to={url}/> <Switch>
<Route exact path="/login" component={Login} /> <Redirect exact from="/" to={url}/>
<Route path="/logout" component={Logout} /> <Route exact path="/login" component={Login} />
<ProtectedRoute <Route path="/logout" component={Logout} />
exact <ProtectedRoute
path="/repos" exact
component={Overview} path="/repos"
authenticated={authenticated} component={Overview}
/> authenticated={authenticated}
<ProtectedRoute />
exact <ProtectedRoute
path="/repos/create" exact
component={Create} path="/repos/create"
authenticated={authenticated} component={Create}
/> authenticated={authenticated}
<ProtectedRoute />
exact <ProtectedRoute
path="/repos/:page" exact
component={Overview} path="/repos/:page"
authenticated={authenticated} component={Overview}
/> authenticated={authenticated}
<ProtectedRoute />
path="/repo/:namespace/:name" <ProtectedRoute
component={RepositoryRoot} path="/repo/:namespace/:name"
authenticated={authenticated} component={RepositoryRoot}
/> authenticated={authenticated}
<ProtectedRoute />
exact <ProtectedRoute
path="/users" exact
component={Users} path="/users"
authenticated={authenticated} component={Users}
/> authenticated={authenticated}
<ProtectedRoute />
authenticated={authenticated} <ProtectedRoute
path="/users/add" authenticated={authenticated}
component={AddUser} path="/users/add"
/> component={AddUser}
<ProtectedRoute />
exact <ProtectedRoute
path="/users/:page" exact
component={Users} path="/users/:page"
authenticated={authenticated} component={Users}
/> authenticated={authenticated}
<ProtectedRoute />
authenticated={authenticated} <ProtectedRoute
path="/user/:name" authenticated={authenticated}
component={SingleUser} path="/user/:name"
/> component={SingleUser}
/>
<ProtectedRoute <ProtectedRoute
exact exact
path="/groups" path="/groups"
component={Groups} component={Groups}
authenticated={authenticated} authenticated={authenticated}
/> />
<ProtectedRoute <ProtectedRoute
authenticated={authenticated} authenticated={authenticated}
path="/group/:name" path="/group/:name"
component={SingleGroup} component={SingleGroup}
/> />
<ProtectedRoute <ProtectedRoute
authenticated={authenticated} authenticated={authenticated}
path="/groups/add" path="/groups/add"
component={AddGroup} component={AddGroup}
/> />
<ProtectedRoute <ProtectedRoute
exact exact
path="/groups/:page" path="/groups/:page"
component={Groups} component={Groups}
authenticated={authenticated} authenticated={authenticated}
/> />
<ProtectedRoute <ProtectedRoute
path="/config" path="/config"
component={Config} component={Config}
authenticated={authenticated} authenticated={authenticated}
/> />
<ProtectedRoute <ProtectedRoute
path="/me" path="/me"
component={Profile} component={Profile}
authenticated={authenticated} authenticated={authenticated}
/> />
<ExtensionPoint <ExtensionPoint
name="main.route" name="main.route"
renderAll={true} renderAll={true}
props={{authenticated, links}} props={{authenticated, links}}
/> />
</Switch> </Switch>
</div> </div>
</ErrorBoundary>
); );
} }
} }