Skip to content

Commit

Permalink
ui: create error Boundary component
Browse files Browse the repository at this point in the history
Previously, when there was an error on the pages on the console
it would crash and nothing would load. This commit introduces
an error boundary, making an error message show instead of the
blank page.

Release note (ui change): New page for when something goes wrong
and the page crashes.
  • Loading branch information
maryliag committed Nov 15, 2021
1 parent 96fef3f commit be9c596
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 11 deletions.
55 changes: 55 additions & 0 deletions pkg/ui/workspaces/db-console/assets/sleepy-moon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions pkg/ui/workspaces/db-console/src/app.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { EnqueueRange } from "src/views/reports/containers/enqueueRange";
import { RangesMain } from "src/views/devtools/containers/raftRanges";
import { RaftMessages } from "src/views/devtools/containers/raftMessages";
import Raft from "src/views/devtools/containers/raft";
import NotFound from "src/views/app/components/NotFound";
import NotFound from "src/views/app/components/errorMessage/notFound";
import { ProblemRanges } from "src/views/reports/containers/problemRanges";
import { Localities } from "src/views/reports/containers/localities";
import { Nodes } from "src/views/reports/containers/nodes";
Expand Down Expand Up @@ -580,7 +580,7 @@ describe("Routing to", () => {
});

describe("'/unknown-url' path", () => {
it("routes to <NotFound> component", () => {
it("routes to <errorMessage> component", () => {
navigateToPath("/some-random-ulr");
assert.lengthOf(appWrapper.find(NotFound), 1);
});
Expand Down
2 changes: 1 addition & 1 deletion pkg/ui/workspaces/db-console/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
tabAttr,
tableNameAttr,
} from "src/util/constants";
import NotFound from "src/views/app/components/NotFound";
import NotFound from "src/views/app/components/errorMessage/notFound";
import Layout from "src/views/app/containers/layout";
import DataDistributionPage from "src/views/cluster/containers/dataDistribution";
import { EventPage } from "src/views/cluster/containers/events";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2021 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

import React, { ErrorInfo } from "react";
import Helmet from "react-helmet";
import "./errorMessage.styl";
import SleepyMoonImg from "assets/sleepy-moon.svg";

interface ErrorBoundaryProps {
onCatch?: (error: Error, errorInfo: ErrorInfo) => void;
}

interface ErrorBoundaryState {
hasError: boolean;
error: Error | undefined;
}

// ErrorBoundary with image and text message.
export default class ErrorBoundary extends React.Component<
ErrorBoundaryProps,
ErrorBoundaryState
> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = {
hasError: false,
error: undefined,
};
}

static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}

componentDidCatch(error: Error, errorInfo: ErrorInfo) {
// Console.error for developer visibility.
console.error(error);
this.props.onCatch && this.props.onCatch(error, errorInfo);
}

render() {
if (!this.state.hasError) {
return this.props.children;
}
return (
<main className="error-message-page">
<Helmet title="Error" />
<div className="error-message-page__content">
<img className="error-message-page__img" src={SleepyMoonImg} />
<div className="error-message-page__body">
<div className="error-message-page__message">
Something went wrong.
</div>
<p>
There is a problem loading the component of this page. Try
refreshing the page.
</p>
</div>
</div>
</main>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@require '~src/components/core/index'

.not-found-page
.error-message-page
min-width 320px
&__content
display flex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@

import React from "react";
import Helmet from "react-helmet";
import "./notFound.styl";
import "./errorMessage.styl";
import NotFoundImg from "assets/not-found.svg";

function NotFound() {
return (
<main className="not-found-page">
<main className="error-message-page">
<Helmet title="Not Found" />
<div className="not-found-page__content">
<div className="error-message-page__content">
<img
className="not-found-page__img"
className="error-message-page__img"
src={NotFoundImg}
alt="404 Error"
/>
<div className="not-found-page__body">
<div className="not-found-page__message">Whoops!</div>
<div className="error-message-page__body">
<div className="error-message-page__message">Whoops!</div>
<p>
We can&apos;t find the page you are looking for. You may have typed
the wrong address or found a broken link.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { RouteComponentProps, withRouter } from "react-router-dom";
import { connect } from "react-redux";

import NavigationBar from "src/views/app/components/layoutSidebar";
import ErrorBoundary from "src/views/app/components/errorMessage/errorBoundary";
import TimeWindowManager from "src/views/app/containers/timewindow";
import AlertBanner from "src/views/app/containers/alertBanner";
import RequireLogin from "src/views/login/requireLogin";
Expand Down Expand Up @@ -99,7 +100,7 @@ class Layout extends React.Component<LayoutProps & RouteComponentProps> {
<NavigationBar />
</div>
<div ref={this.contentRef} className="layout-panel__content">
{this.props.children}
<ErrorBoundary>{this.props.children}</ErrorBoundary>
</div>
</div>
</div>
Expand Down

0 comments on commit be9c596

Please sign in to comment.