Skip to content

Commit 66bc556

Browse files
authored
Merge pull request #502 from Yashsharma1911/yash/updateErrorBoundaries
Enhance error boundaries
2 parents f71f14c + 3fc10a5 commit 66bc556

File tree

8 files changed

+201
-14
lines changed

8 files changed

+201
-14
lines changed

src/custom/ErrorBoundary/ErrorBoundary.tsx

+6-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ interface FallbackComponentProps extends FallbackProps {
2525
children?: React.ReactNode;
2626
}
2727

28-
function Fallback({ error, children }: FallbackComponentProps): JSX.Element {
28+
export function Fallback({ error, children }: FallbackComponentProps): JSX.Element {
2929
return (
3030
<div role="alert">
3131
<h2>Uh-oh!😔 Please pardon the mesh.</h2>
@@ -62,12 +62,13 @@ const reportError = (error: Error, info: React.ErrorInfo): void => {
6262
};
6363

6464
interface ErrorBoundaryProps {
65+
customFallback?: React.ComponentType<FallbackProps>;
6566
children: React.ReactNode;
6667
}
6768

68-
export const ErrorBoundary: React.FC<ErrorBoundaryProps> = ({ children }) => {
69+
export const ErrorBoundary: React.FC<ErrorBoundaryProps> = ({ customFallback, children }) => {
6970
return (
70-
<ReactErrorBoundary FallbackComponent={Fallback} onError={reportError}>
71+
<ReactErrorBoundary FallbackComponent={customFallback ?? Fallback} onError={reportError}>
7172
{children}
7273
</ReactErrorBoundary>
7374
);
@@ -79,7 +80,7 @@ interface WithErrorBoundaryProps {
7980
errorHandlingProps?: ErrorBoundaryProps;
8081
}
8182

82-
export const WithErrorBoundary: React.FC<WithErrorBoundaryProps> = ({
83+
export const withErrorBoundary: React.FC<WithErrorBoundaryProps> = ({
8384
Component,
8485
errorHandlingProps = { children: null }
8586
}: WithErrorBoundaryProps): JSX.Element => {
@@ -99,7 +100,7 @@ export const withSuppressedErrorBoundary: React.FC<WithSuppressedErrorBoundaryPr
99100
Component
100101
}: WithSuppressedErrorBoundaryProps): JSX.Element => {
101102
return (
102-
<ReactErrorBoundary FallbackComponent={Fallback} onError={reportError}>
103+
<ReactErrorBoundary FallbackComponent={() => null} onError={reportError}>
103104
<Component />
104105
</ReactErrorBoundary>
105106
);

src/custom/ErrorBoundary/README.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
## Error Boundary Components
2+
3+
### `ErrorBoundary`
4+
5+
The `ErrorBoundary` component is designed to catch errors that occur within its child components and provide a customizable fallback UI when an error occurs.
6+
7+
#### Usage
8+
9+
Wrap your component with the `ErrorBoundary`:
10+
11+
```tsx
12+
import { ErrorBoundary } from '@layer5/sistent';
13+
14+
const MyComponent = () => {
15+
// Your component logic
16+
17+
return <ErrorBoundary>{/* Your component JSX */}</ErrorBoundary>;
18+
};
19+
```
20+
21+
##### Custom Fallback
22+
23+
You can provide a custom fallback component to `ErrorBoundary`:
24+
25+
```tsx
26+
const MyComponent = () => {
27+
// Your component logic
28+
29+
return (
30+
<ErrorBoundary customFallback={CustomFallbackComponent}>
31+
{/* Your component JSX */}
32+
</ErrorBoundary>
33+
);
34+
};
35+
```
36+
37+
### `withErrorBoundary`
38+
39+
`withErrorBoundary` is a higher-order component (HOC) that simplifies wrapping a component with ErrorBoundary. It uses default fallback component. This can be useFul to wrap child components
40+
41+
#### Usage
42+
43+
Wrap your component using `withErrorBoundary`:
44+
45+
```tsx
46+
import { withErrorBoundary } from '@layer5/sistent';
47+
48+
const MyComponent = withErrorBoundary(() => {
49+
return {
50+
/* Your component JSX */
51+
};
52+
});
53+
```
54+
55+
### `withSuppressedErrorBoundary`
56+
57+
`withSuppressedErrorBoundary` is another HOC that suppresses the error in browser's console instead of displaying fallback component to users, this can be useFull for errors that are not critical and can be avoided.
58+
59+
#### Usage
60+
61+
Wrap your component using withSuppressedErrorBoundary:
62+
63+
```tsx
64+
import { withSuppressedErrorBoundary } from '@layer5/sistent';
65+
66+
const MyComponent = withSuppressedErrorBoundary(() => {
67+
return {
68+
/* Your component JSX */
69+
};
70+
});
71+
```
72+
73+
### Handling Different Levels of Errors
74+
75+
#### Critical Errors
76+
77+
Critical errors typically originate from parent or root components and can potentially lead to the entire page crashing. In such cases, it is recommended to use the ErrorBoundary with either the default fallback component or a custom fallback component to ensure users receive assistance.
78+
79+
#### Non-critical Errors
80+
81+
Non-critical errors occur in child components and may not result in a page crash or hinder users from performing other operations. In these cases, displaying the error through a toaster notification or handling it as an event can be beneficial.
82+
83+
#### Errors That Can Be Avoided
84+
85+
In some scenarios, a child component might encounter an error that doesn't block users and doesn't require immediate attention. Such errors can be avoided and suppressed into the browser's console for debugging purposes. The `withSuppressedErrorBoundary` higher-order component (HOC) function can be useful in this scenario.

src/custom/ErrorBoundary/index.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1-
export { ErrorBoundary, WithErrorBoundary, withSuppressedErrorBoundary } from './ErrorBoundary';
1+
export {
2+
ErrorBoundary,
3+
Fallback,
4+
withErrorBoundary,
5+
withSuppressedErrorBoundary
6+
} from './ErrorBoundary';

src/custom/index.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import {
55
CustomColumnVisibilityControlProps
66
} from './CustomColumnVisibilityControl/CustomColumnVisibilityControl';
77
import { EmptyState } from './EmptyState';
8-
import { ErrorBoundary, WithErrorBoundary, withSuppressedErrorBoundary } from './ErrorBoundary';
8+
import {
9+
ErrorBoundary,
10+
Fallback,
11+
withErrorBoundary,
12+
withSuppressedErrorBoundary
13+
} from './ErrorBoundary';
914
import { FlipCard } from './FlipCard';
1015
import { useWindowDimensions } from './Helpers/Dimension';
1116
import { useNotificationHandler } from './Helpers/Notification';
@@ -22,15 +27,16 @@ export {
2227
CustomColumnVisibilityControl,
2328
EmptyState,
2429
ErrorBoundary,
30+
Fallback,
2531
FlipCard,
2632
PopperListener,
2733
ResponsiveDataTable,
2834
SearchBar,
2935
StyledTooltip,
3036
UniversalFilter,
31-
WithErrorBoundary,
3237
useNotificationHandler,
3338
useWindowDimensions,
39+
withErrorBoundary,
3440
withSuppressedErrorBoundary
3541
};
3642
export type {

src/schemas/createAndEditEnvironment/schema.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@ const createAndEditEnvironmentSchema = {
22
title: 'Environment',
33
properties: {
44
description: {
5-
description: 'Description of the Environment',
5+
description:
6+
'An environment is a collection of resources, such as connections & credentail. Provide a detailed description to clarify the purpose of this environment and the types of resources it encompasses. You can modify the description at any time. Learn more about environments [here](https://docs.meshery.io/concepts/logical/environments).',
67
format: 'textarea',
78
title: 'Description',
89
type: 'string',
910
'x-rjsf-grid-area': '12'
1011
},
1112
name: {
1213
description:
13-
"Enter a unique and meaningful name for the environment. Remember you can change name of environment after it's creation too",
14+
'An environment is a collection of resources. Provide a name that meaningfully represents these resources. You can change the name of the environment even after its creation.',
1415
title: 'Name',
1516
type: 'string',
1617
'x-rjsf-grid-area': '12'
1718
},
1819
organization: {
1920
type: 'string',
2021
title: 'Organization',
21-
description: 'Select a organization in whic',
22+
description:
23+
'Select an organization in which you want to create this new environment. Keep in mind that the organization cannot be changed after creation.',
2224
enum: [],
2325
enumNames: [],
2426
'x-rjsf-grid-area': '12'

src/schemas/createAndEditWorkspace/schema.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@
44
const createAndEditWorkspace = {
55
properties: {
66
description: {
7-
description: 'Description of the Workspace',
7+
description:
8+
"Workspaces serve as a virtual space for your team-based work, allows you to control access and more, Provide a detailed description to clarify the purpose of this workspace. Remember you can changes description of workspace after it's creations too. Learn more about workspaces [here](https://docs.meshery.io/concepts/logical/workspaces)",
89
format: 'textarea',
910
title: 'Description',
1011
type: 'string',
1112
'x-rjsf-grid-area': '12'
1213
},
1314
name: {
14-
description: 'The name of Workspace',
15+
description:
16+
'Provide a name that meaningfully represents this workspace. You can change the name of the workspace even after its creation.',
1517
title: 'Name',
1618
type: 'string',
1719
'x-rjsf-grid-area': '12'
1820
},
1921
organization: {
2022
type: 'string',
23+
description:
24+
'Select an organization in which you want to create this new workspace. Keep in mind that the organization cannot be changed after creation.',
2125
title: 'Organization',
2226
enum: [],
2327
enumNames: [],

src/schemas/index.tsx

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,37 @@
11
import helpAndSupportModalSchema from './helpAndSupportModal/schema';
22
import helpAndSupportModalUiSchema from './helpAndSupportModal/uiSchema';
33

4-
export { helpAndSupportModalSchema, helpAndSupportModalUiSchema };
4+
import createAndEditEnvironmentSchema from './createAndEditEnvironment/schema';
5+
import createAndEditEnvironmentUiSchema from './createAndEditEnvironment/uiSchema';
6+
7+
import createAndEditWorkspaceSchema from './createAndEditWorkspace/schema';
8+
import createAndEditWorkspaceUiSchema from './createAndEditWorkspace/uiSchema';
9+
10+
import helmConnectionSchema from './helmConnection/schema';
11+
import helmConnectionUiSchema from './helmConnection/uiSchema';
12+
13+
import importDesignSchema from './importDesign/schema';
14+
import importDesignUiSchema from './importDesign/uiSchema';
15+
16+
import importFilterSchema from './importFilter/schema';
17+
import importFilterUiSchema from './importFilter/uiSchema';
18+
19+
import publishCatalogItemSchema from './publishCatalogItem/schema';
20+
import publishCatalogItemUiSchema from './publishCatalogItem/uiSchema';
21+
22+
export {
23+
createAndEditEnvironmentSchema,
24+
createAndEditEnvironmentUiSchema,
25+
createAndEditWorkspaceSchema,
26+
createAndEditWorkspaceUiSchema,
27+
helmConnectionSchema,
28+
helmConnectionUiSchema,
29+
helpAndSupportModalSchema,
30+
helpAndSupportModalUiSchema,
31+
importDesignSchema,
32+
importDesignUiSchema,
33+
importFilterSchema,
34+
importFilterUiSchema,
35+
publishCatalogItemSchema,
36+
publishCatalogItemUiSchema
37+
};

src/schemas/readme.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# RJSF Schemas
2+
3+
RJSF, or React JSON Schema Form, schemas play a crucial role in defining the structure and behavior of forms. These schemas, written in JSON format, provide a blueprint for rendering forms dynamically and handling user input effectively.
4+
5+
### What are RJSF Schemas?
6+
7+
RJSF Schemas, based on the React JSON Schema Form library, define the structure, validation rules, and UI elements of dynamic forms in a standardized way. They enable the creation of consistent and flexible forms across our applications.
8+
9+
### How to Use RJSF Schemas
10+
11+
1. **Importing Schemas:**
12+
Include the required schema in your React component by importing it. For example:
13+
14+
```javascript
15+
import MyFormSchema from '@layer5/sistent';
16+
```
17+
18+
1. **Rendering Forms:**
19+
Integrate the schema into your component to render the form dynamically. Use already created generic RJSF components or use RJSF Form component directly.
20+
21+
```javascript
22+
import { sampleSchema, sampleUiSchema } from '@layer5/sistent';
23+
<Form schema={sampleSchema} uiSchema={sampleUiSchema} onSubmit={handleFormSubmission} />;
24+
```
25+
26+
1. **Customization:**
27+
Adjust the schema properties to tailor the form's appearance and behavior. Refer to the specific schema's documentation for customization options.
28+
29+
### File Conventions for Schemas
30+
31+
Follow a consistent file structure convention to enhance clarity and organization when adding new schema:
32+
33+
1. Use the same name as the schema for the directory.
34+
1. Use CamelCase for multi-word schema names, e.g., UserRegistrationFormSchema.
35+
1. Create two separate files, schema.tsx and uiSchema.tsx, to store both schemas separately.
36+
37+
### Naming Conventions for Schemas
38+
39+
Follow a consistent naming convention to enhance clarity and organization when adding new schema:
40+
41+
1. Use descriptive names that convey the purpose of the form.
42+
1. CamelCase for multi-word schema names, e.g., UserRegistrationFormSchema.
43+
1. Include "Schema" in the name to explicitly indicate that it's a schema, e.g., ProfileSettingsSchema.
44+
1. Include "UiSchema" in the name to explicitly indicate that it's a UI schema, e.g., ProfileSettingsUiSchema.
45+
46+
### Custom Properties
47+
48+
In addition to the properties offered by the JSON schema, we have introduced the following custom properties that you can include in new schema:
49+
50+
1. `x-rjsf-grid-area:` This property accepts an integer that defines the width of the field. For instance, specifying 6 means it will take up half of the parent width, while 12 signifies full width.
51+
1. `x-encode-in-uri:` When set to true, this property enables RJSF to encode data in URI format and return it.

0 commit comments

Comments
 (0)