From be9c596d92a55c405933016ce5396f38647da69a Mon Sep 17 00:00:00 2001 From: Marylia Gutierrez Date: Mon, 15 Nov 2021 13:43:46 -0500 Subject: [PATCH] ui: create error Boundary component 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. --- .../db-console/assets/sleepy-moon.svg | 55 +++++++++++++++ pkg/ui/workspaces/db-console/src/app.spec.tsx | 4 +- pkg/ui/workspaces/db-console/src/app.tsx | 2 +- .../components/errorMessage/errorBoundary.tsx | 70 +++++++++++++++++++ .../errorMessage.styl} | 2 +- .../index.tsx => errorMessage/notFound.tsx} | 12 ++-- .../src/views/app/containers/layout/index.tsx | 3 +- 7 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 pkg/ui/workspaces/db-console/assets/sleepy-moon.svg create mode 100644 pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorBoundary.tsx rename pkg/ui/workspaces/db-console/src/views/app/components/{NotFound/notFound.styl => errorMessage/errorMessage.styl} (97%) rename pkg/ui/workspaces/db-console/src/views/app/components/{NotFound/index.tsx => errorMessage/notFound.tsx} (74%) diff --git a/pkg/ui/workspaces/db-console/assets/sleepy-moon.svg b/pkg/ui/workspaces/db-console/assets/sleepy-moon.svg new file mode 100644 index 000000000000..1c60daf68c27 --- /dev/null +++ b/pkg/ui/workspaces/db-console/assets/sleepy-moon.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/ui/workspaces/db-console/src/app.spec.tsx b/pkg/ui/workspaces/db-console/src/app.spec.tsx index 00930530a3f9..b5e6d5d66402 100644 --- a/pkg/ui/workspaces/db-console/src/app.spec.tsx +++ b/pkg/ui/workspaces/db-console/src/app.spec.tsx @@ -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"; @@ -580,7 +580,7 @@ describe("Routing to", () => { }); describe("'/unknown-url' path", () => { - it("routes to component", () => { + it("routes to component", () => { navigateToPath("/some-random-ulr"); assert.lengthOf(appWrapper.find(NotFound), 1); }); diff --git a/pkg/ui/workspaces/db-console/src/app.tsx b/pkg/ui/workspaces/db-console/src/app.tsx index 97a2c7c19b07..9a232faf84c0 100644 --- a/pkg/ui/workspaces/db-console/src/app.tsx +++ b/pkg/ui/workspaces/db-console/src/app.tsx @@ -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"; diff --git a/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorBoundary.tsx b/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorBoundary.tsx new file mode 100644 index 000000000000..3d23256e908d --- /dev/null +++ b/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorBoundary.tsx @@ -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 ( +
+ +
+ +
+
+ Something went wrong. +
+

+ There is a problem loading the component of this page. Try + refreshing the page. +

+
+
+
+ ); + } +} diff --git a/pkg/ui/workspaces/db-console/src/views/app/components/NotFound/notFound.styl b/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorMessage.styl similarity index 97% rename from pkg/ui/workspaces/db-console/src/views/app/components/NotFound/notFound.styl rename to pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorMessage.styl index 16c8464ac8a9..72421bb4f6cb 100644 --- a/pkg/ui/workspaces/db-console/src/views/app/components/NotFound/notFound.styl +++ b/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/errorMessage.styl @@ -10,7 +10,7 @@ @require '~src/components/core/index' -.not-found-page +.error-message-page min-width 320px &__content display flex diff --git a/pkg/ui/workspaces/db-console/src/views/app/components/NotFound/index.tsx b/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/notFound.tsx similarity index 74% rename from pkg/ui/workspaces/db-console/src/views/app/components/NotFound/index.tsx rename to pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/notFound.tsx index e22d4c64da73..91950e843fcc 100644 --- a/pkg/ui/workspaces/db-console/src/views/app/components/NotFound/index.tsx +++ b/pkg/ui/workspaces/db-console/src/views/app/components/errorMessage/notFound.tsx @@ -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 ( -
+
-
+
404 Error -
-
Whoops!
+
+
Whoops!

We can't find the page you are looking for. You may have typed the wrong address or found a broken link. diff --git a/pkg/ui/workspaces/db-console/src/views/app/containers/layout/index.tsx b/pkg/ui/workspaces/db-console/src/views/app/containers/layout/index.tsx index 61da39b8a640..7cf797c863f6 100644 --- a/pkg/ui/workspaces/db-console/src/views/app/containers/layout/index.tsx +++ b/pkg/ui/workspaces/db-console/src/views/app/containers/layout/index.tsx @@ -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"; @@ -99,7 +100,7 @@ class Layout extends React.Component {

- {this.props.children} + {this.props.children}