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 { default as Autocomplete} from "./Autocomplete";
export { default as BranchSelector } from "./BranchSelector";
export { default as ErrorBoundary } from "./ErrorBoundary";
export { apiClient } from "./apiclient.js";
export * from "./errors";

View File

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

View File

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