Skip to content

Commit ab6768e

Browse files
Merge pull request openshift#12170 from jcaianirh/expose-error-boundary
CONSOLE-3276: Expose ErrorBoundary capabilities in the SDK
2 parents 597489c + ec103d2 commit ab6768e

File tree

15 files changed

+189
-15
lines changed

15 files changed

+189
-15
lines changed

dynamic-demo-plugin/console-extensions.json

+17
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,23 @@
360360
"href": "/test-modal"
361361
}
362362
},
363+
{
364+
"type": "console.page/route",
365+
"properties": {
366+
"path": "/sample-error-boundary-page",
367+
"component": { "$codeRef": "sampleErrorBoundaryPage.default" }
368+
}
369+
},
370+
{
371+
"type": "console.navigation/href",
372+
"properties": {
373+
"id": "error-boundary-page",
374+
"perspective": "admin",
375+
"section": "admin-demo-section",
376+
"name": "%plugin__console-demo-plugin~Sample Error Boundary Page%",
377+
"href": "/sample-error-boundary-page"
378+
}
379+
},
363380
{
364381
"type": "console.page/route",
365382
"properties": {

dynamic-demo-plugin/locales/en/plugin__console-demo-plugin.json

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"{{count}} Worker Node_plural": "{{count}} Worker Node",
44
"Worker Nodes": "Worker Nodes",
55
"Custom Overview Detail Info": "Custom Overview Detail Info",
6+
"Oops something went wrong in your dynamic plug-in": "Oops something went wrong in your dynamic plug-in",
7+
"Sample Error Boundary Page": "Sample Error Boundary Page",
8+
"Create an exception": "Create an exception",
9+
"Launch buggy component": "Launch buggy component",
610
"Example page with a namespace bar": "Example page with a namespace bar",
711
"Currently selected namespace": "Currently selected namespace",
812
"Example info alert": "Example info alert",

dynamic-demo-plugin/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@
6868
"customOverviewDetailItem": "./components/CustomOverviewDetailItem",
6969
"projectOverviewInventory": "./components/ProjectOverview/Inventory",
7070
"projectOverview": "./utils/project-overview",
71-
"modalPage": "./components/Modals/ModalPage"
71+
"modalPage": "./components/Modals/ModalPage",
72+
"sampleErrorBoundaryPage": "./components/ErrorBoundary/SampleErrorBoundaryPage"
7273
},
7374
"dependencies": {
7475
"@console/pluginAPI": "*"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import * as React from 'react';
2+
import { withTranslation } from 'react-i18next';
3+
import { TFunction } from 'i18next';
4+
import { ErrorBoundaryFallbackProps } from "@openshift-console/dynamic-plugin-sdk";
5+
6+
type DemoErrorBoundaryState = {
7+
error: { message: string; stack: string; name: string };
8+
errorInfo: { componentStack: string };
9+
};
10+
11+
type DemoErrorBoundaryProps = {
12+
FallbackComponent?: React.ComponentType<ErrorBoundaryFallbackProps>;
13+
t: TFunction;
14+
};
15+
16+
const DefaultFallback: React.FC = () => <div />;
17+
18+
class DemoErrorBoundaryWithTranslation extends React.Component<DemoErrorBoundaryProps, DemoErrorBoundaryState> {
19+
constructor(props) {
20+
super(props);
21+
this.state = { error: null, errorInfo: null };
22+
}
23+
24+
componentDidCatch(error, errorInfo) {
25+
this.setState({
26+
error,
27+
errorInfo,
28+
});
29+
}
30+
31+
render() {
32+
const { t } = this.props;
33+
const { error, errorInfo } = this.state;
34+
const FallbackComponent = this.props.FallbackComponent || DefaultFallback;
35+
if (error) {
36+
return <FallbackComponent title={t('plugin__console-demo-plugin~Oops something went wrong in your dynamic plug-in')} errorMessage={error?.message} componentStack={errorInfo?.componentStack} stack={error?.stack} />;
37+
}
38+
return this.props.children;
39+
}
40+
}
41+
42+
export const DemoErrorBoundary = withTranslation()(DemoErrorBoundaryWithTranslation);
43+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as React from 'react';
2+
import { useTranslation } from "react-i18next";
3+
import { Button, Card, CardBody, CardTitle, Page, PageSection, Title } from "@patternfly/react-core";
4+
import { ErrorBoundaryFallbackPage } from '@openshift-console/dynamic-plugin-sdk';
5+
import { DemoErrorBoundary } from './DemoErrorBoundary';
6+
7+
const BuggyComponent: React.FC = () => {
8+
throw new Error('test error');
9+
}
10+
11+
const SampleErrorBoundaryPage: React.FC = () => {
12+
const { t } = useTranslation("plugin__console-demo-plugin");
13+
const [ isBuggyComponentRendered, setBuggyComponentRendered ] = React.useState(false);
14+
const onClick = () => {setBuggyComponentRendered(!isBuggyComponentRendered)};
15+
16+
return (
17+
<DemoErrorBoundary FallbackComponent={ErrorBoundaryFallbackPage}>
18+
<Page
19+
additionalGroupedContent={
20+
<PageSection variant="light">
21+
<Title headingLevel="h1">{t('Sample Error Boundary Page')}</Title>
22+
</PageSection>
23+
}
24+
>
25+
<PageSection>
26+
<Card>
27+
<CardTitle>{t("Create an exception")}</CardTitle>
28+
<CardBody>
29+
<Button onClick={onClick}>{t('Launch buggy component')}</Button>
30+
{isBuggyComponentRendered && <BuggyComponent/>}
31+
</CardBody>
32+
</Card>
33+
</PageSection>
34+
</Page>
35+
</DemoErrorBoundary>
36+
);
37+
};
38+
39+
export default SampleErrorBoundaryPage;

dynamic-demo-plugin/src/i18n.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
// t('plugin__console-demo-plugin~Bar item')
1515
// t('plugin__console-demo-plugin~Custom Overview Detail Title')
1616
// t('plugin__console-demo-plugin~Example Namespaced Page')
17+
// t('plugin__console-demo-plugin~Sample Error Boundary Page')

frontend/packages/console-dynamic-plugin-sdk/docs/api.md

+45-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@
6161
59. [`useModal`](#usemodal)
6262
60. [`ActionServiceProvider`](#actionserviceprovider)
6363
61. [`NamespaceBar`](#namespacebar)
64-
62. [DEPRECATED] [`PerspectiveContext`](#perspectivecontext)
65-
63. [DEPRECATED] [`useAccessReviewAllowed`](#useaccessreviewallowed)
66-
64. [DEPRECATED] [`useSafetyFirst`](#usesafetyfirst)
64+
62. [`ErrorBoundaryFallbackPage`](#errorboundaryfallbackpage)
65+
63. [DEPRECATED] [`PerspectiveContext`](#perspectivecontext)
66+
64. [DEPRECATED] [`useAccessReviewAllowed`](#useaccessreviewallowed)
67+
65. [DEPRECATED] [`useSafetyFirst`](#usesafetyfirst)
6768

6869
---
6970

@@ -2119,6 +2120,47 @@ A component that renders a horizontal toolbar with a namespace dropdown menu in
21192120

21202121

21212122

2123+
---
2124+
2125+
## `ErrorBoundaryFallbackPage`
2126+
2127+
### Summary
2128+
2129+
Creates full page ErrorBoundaryFallbackPage component to display the "Oh no! Something went wrong."<br/>message along with the stack trace and other helpful debugging information. This is to be used in<br/>conjunction with an <ErrorBoundary> component.
2130+
2131+
2132+
2133+
### Example
2134+
2135+
2136+
```tsx
2137+
//in ErrorBoundary component
2138+
return (
2139+
if (this.state.hasError) {
2140+
return <ErrorBoundaryFallbackPage errorMessage={errorString} componentStack={componentStackString}
2141+
stack={stackTraceString} title={errorString}/>;
2142+
}
2143+
2144+
return this.props.children;
2145+
}
2146+
)
2147+
```
2148+
2149+
2150+
2151+
2152+
2153+
### Parameters
2154+
2155+
| Parameter Name | Description |
2156+
| -------------- | ----------- |
2157+
| `errorMessage` | text description of the error message |
2158+
| `componentStack` | component trace of the exception |
2159+
| `stack` | stack trace of the exception |
2160+
| `title` | title to render as the header of the error boundary page |
2161+
2162+
2163+
21222164
---
21232165
21242166
## `PerspectiveContext`

frontend/packages/console-dynamic-plugin-sdk/src/api/dynamic-core-api.ts

+27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import * as React from 'react';
33
import { ActionServiceProviderProps } from '../extensions/actions';
44
import {
5+
ErrorBoundaryFallbackProps,
56
HorizontalNavProps,
67
UseResolvedExtensions,
78
VirtualizedTableFC,
@@ -694,3 +695,29 @@ export const ActionServiceProvider: React.FC<ActionServiceProviderProps> = requi
694695
*/
695696
export const NamespaceBar: React.FC<NamespaceBarProps> = require('@console/internal/components/namespace-bar')
696697
.NamespaceBar;
698+
699+
/**
700+
* Creates full page ErrorBoundaryFallbackPage component to display the "Oh no! Something went wrong."
701+
* message along with the stack trace and other helpful debugging information. This is to be used in
702+
* conjunction with an <ErrorBoundary> component.
703+
*
704+
* @param {string} errorMessage - text description of the error message
705+
* @param {string} componentStack - component trace of the exception
706+
* @param {string} stack - stack trace of the exception
707+
* @param {string} title - title to render as the header of the error boundary page
708+
* @example
709+
* ```tsx
710+
* //in ErrorBoundary component
711+
* return (
712+
* if (this.state.hasError) {
713+
* return <ErrorBoundaryFallbackPage errorMessage={errorString} componentStack={componentStackString}
714+
* stack={stackTraceString} title={errorString}/>;
715+
* }
716+
*
717+
* return this.props.children;
718+
* }
719+
* )
720+
* ```
721+
*/
722+
export const ErrorBoundaryFallbackPage: React.FC<ErrorBoundaryFallbackProps> = require('@console/shared/src/components/error/fallbacks/ErrorBoundaryFallbackPage')
723+
.default;

frontend/packages/console-dynamic-plugin-sdk/src/extensions/console-types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -654,3 +654,10 @@ export type NamespaceBarProps = {
654654
isDisabled?: boolean;
655655
children?: React.ReactNode;
656656
};
657+
658+
export type ErrorBoundaryFallbackProps = {
659+
errorMessage: string;
660+
componentStack: string;
661+
stack: string;
662+
title: string;
663+
};

frontend/packages/console-shared/src/components/error/error-boundary.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
2+
import { ErrorBoundaryFallbackProps } from '@console/dynamic-plugin-sdk';
23
import { history } from '@console/internal/components/utils/router';
3-
import { ErrorBoundaryFallbackProps } from './types';
44

55
type ErrorBoundaryProps = {
66
FallbackComponent?: React.ComponentType<ErrorBoundaryFallbackProps>;

frontend/packages/console-shared/src/components/error/fallbacks/ErrorBoundaryFallbackInline.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { Alert, Button, Modal, ModalVariant, Split, SplitItem } from '@patternfly/react-core';
33
import { useTranslation } from 'react-i18next';
4-
import { ErrorBoundaryFallbackProps } from '../types';
4+
import { ErrorBoundaryFallbackProps } from '@console/dynamic-plugin-sdk';
55
import ErrorDetailsBlock from './ErrorDetailsBlock';
66

77
/**

frontend/packages/console-shared/src/components/error/fallbacks/ErrorBoundaryFallbackPage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react';
22
import { Text, TextVariants } from '@patternfly/react-core';
33
import { useTranslation } from 'react-i18next';
4+
import { ErrorBoundaryFallbackProps } from '@console/dynamic-plugin-sdk';
45
import { ExpandCollapse } from '@console/internal/components/utils/expand-collapse';
5-
import { ErrorBoundaryFallbackProps } from '../types';
66
import ErrorDetailsBlock from './ErrorDetailsBlock';
77

88
/**

frontend/packages/console-shared/src/components/error/fallbacks/ErrorDetailsBlock.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { useTranslation } from 'react-i18next';
3+
import { ErrorBoundaryFallbackProps } from '@console/dynamic-plugin-sdk';
34
import { CopyToClipboard } from '@console/internal/components/utils/copy-to-clipboard';
4-
import { ErrorBoundaryFallbackProps } from '../types';
55

66
const ErrorDetailsBlock: React.FC<ErrorBoundaryFallbackProps> = (props) => {
77
const { t } = useTranslation();

frontend/packages/console-shared/src/components/error/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Default ErrorBoundary usage
22
export { default as ErrorBoundary } from './error-boundary';
3-
export * from './types';
43

54
// Packaged, easy to use, fallback options
65
export { default as ErrorBoundaryPage } from './fallbacks/ErrorBoundaryPage';

frontend/packages/console-shared/src/components/error/types.ts

-6
This file was deleted.

0 commit comments

Comments
 (0)