Skip to content

Commit

Permalink
Merge pull request #502 from Yashsharma1911/yash/updateErrorBoundaries
Browse files Browse the repository at this point in the history
Enhance error boundaries
  • Loading branch information
nebula-aac authored Feb 12, 2024
2 parents f71f14c + 3fc10a5 commit 66bc556
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 14 deletions.
11 changes: 6 additions & 5 deletions src/custom/ErrorBoundary/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface FallbackComponentProps extends FallbackProps {
children?: React.ReactNode;
}

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

interface ErrorBoundaryProps {
customFallback?: React.ComponentType<FallbackProps>;
children: React.ReactNode;
}

export const ErrorBoundary: React.FC<ErrorBoundaryProps> = ({ children }) => {
export const ErrorBoundary: React.FC<ErrorBoundaryProps> = ({ customFallback, children }) => {
return (
<ReactErrorBoundary FallbackComponent={Fallback} onError={reportError}>
<ReactErrorBoundary FallbackComponent={customFallback ?? Fallback} onError={reportError}>
{children}
</ReactErrorBoundary>
);
Expand All @@ -79,7 +80,7 @@ interface WithErrorBoundaryProps {
errorHandlingProps?: ErrorBoundaryProps;
}

export const WithErrorBoundary: React.FC<WithErrorBoundaryProps> = ({
export const withErrorBoundary: React.FC<WithErrorBoundaryProps> = ({
Component,
errorHandlingProps = { children: null }
}: WithErrorBoundaryProps): JSX.Element => {
Expand All @@ -99,7 +100,7 @@ export const withSuppressedErrorBoundary: React.FC<WithSuppressedErrorBoundaryPr
Component
}: WithSuppressedErrorBoundaryProps): JSX.Element => {
return (
<ReactErrorBoundary FallbackComponent={Fallback} onError={reportError}>
<ReactErrorBoundary FallbackComponent={() => null} onError={reportError}>
<Component />
</ReactErrorBoundary>
);
Expand Down
85 changes: 85 additions & 0 deletions src/custom/ErrorBoundary/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
## Error Boundary Components

### `ErrorBoundary`

The `ErrorBoundary` component is designed to catch errors that occur within its child components and provide a customizable fallback UI when an error occurs.

#### Usage

Wrap your component with the `ErrorBoundary`:

```tsx
import { ErrorBoundary } from '@layer5/sistent';

const MyComponent = () => {
// Your component logic

return <ErrorBoundary>{/* Your component JSX */}</ErrorBoundary>;
};
```

##### Custom Fallback

You can provide a custom fallback component to `ErrorBoundary`:

```tsx
const MyComponent = () => {
// Your component logic

return (
<ErrorBoundary customFallback={CustomFallbackComponent}>
{/* Your component JSX */}
</ErrorBoundary>
);
};
```

### `withErrorBoundary`

`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

#### Usage

Wrap your component using `withErrorBoundary`:

```tsx
import { withErrorBoundary } from '@layer5/sistent';

const MyComponent = withErrorBoundary(() => {
return {
/* Your component JSX */
};
});
```

### `withSuppressedErrorBoundary`

`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.

#### Usage

Wrap your component using withSuppressedErrorBoundary:

```tsx
import { withSuppressedErrorBoundary } from '@layer5/sistent';

const MyComponent = withSuppressedErrorBoundary(() => {
return {
/* Your component JSX */
};
});
```

### Handling Different Levels of Errors

#### Critical Errors

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.

#### Non-critical Errors

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.

#### Errors That Can Be Avoided

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.
7 changes: 6 additions & 1 deletion src/custom/ErrorBoundary/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export { ErrorBoundary, WithErrorBoundary, withSuppressedErrorBoundary } from './ErrorBoundary';
export {
ErrorBoundary,
Fallback,
withErrorBoundary,
withSuppressedErrorBoundary
} from './ErrorBoundary';
10 changes: 8 additions & 2 deletions src/custom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
CustomColumnVisibilityControlProps
} from './CustomColumnVisibilityControl/CustomColumnVisibilityControl';
import { EmptyState } from './EmptyState';
import { ErrorBoundary, WithErrorBoundary, withSuppressedErrorBoundary } from './ErrorBoundary';
import {
ErrorBoundary,
Fallback,
withErrorBoundary,
withSuppressedErrorBoundary
} from './ErrorBoundary';
import { FlipCard } from './FlipCard';
import { useWindowDimensions } from './Helpers/Dimension';
import { useNotificationHandler } from './Helpers/Notification';
Expand All @@ -22,15 +27,16 @@ export {
CustomColumnVisibilityControl,
EmptyState,
ErrorBoundary,
Fallback,
FlipCard,
PopperListener,
ResponsiveDataTable,
SearchBar,
StyledTooltip,
UniversalFilter,
WithErrorBoundary,
useNotificationHandler,
useWindowDimensions,
withErrorBoundary,
withSuppressedErrorBoundary
};
export type {
Expand Down
8 changes: 5 additions & 3 deletions src/schemas/createAndEditEnvironment/schema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ const createAndEditEnvironmentSchema = {
title: 'Environment',
properties: {
description: {
description: 'Description of the Environment',
description:
'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).',
format: 'textarea',
title: 'Description',
type: 'string',
'x-rjsf-grid-area': '12'
},
name: {
description:
"Enter a unique and meaningful name for the environment. Remember you can change name of environment after it's creation too",
'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.',
title: 'Name',
type: 'string',
'x-rjsf-grid-area': '12'
},
organization: {
type: 'string',
title: 'Organization',
description: 'Select a organization in whic',
description:
'Select an organization in which you want to create this new environment. Keep in mind that the organization cannot be changed after creation.',
enum: [],
enumNames: [],
'x-rjsf-grid-area': '12'
Expand Down
8 changes: 6 additions & 2 deletions src/schemas/createAndEditWorkspace/schema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@
const createAndEditWorkspace = {
properties: {
description: {
description: 'Description of the Workspace',
description:
"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)",
format: 'textarea',
title: 'Description',
type: 'string',
'x-rjsf-grid-area': '12'
},
name: {
description: 'The name of Workspace',
description:
'Provide a name that meaningfully represents this workspace. You can change the name of the workspace even after its creation.',
title: 'Name',
type: 'string',
'x-rjsf-grid-area': '12'
},
organization: {
type: 'string',
description:
'Select an organization in which you want to create this new workspace. Keep in mind that the organization cannot be changed after creation.',
title: 'Organization',
enum: [],
enumNames: [],
Expand Down
35 changes: 34 additions & 1 deletion src/schemas/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,37 @@
import helpAndSupportModalSchema from './helpAndSupportModal/schema';
import helpAndSupportModalUiSchema from './helpAndSupportModal/uiSchema';

export { helpAndSupportModalSchema, helpAndSupportModalUiSchema };
import createAndEditEnvironmentSchema from './createAndEditEnvironment/schema';
import createAndEditEnvironmentUiSchema from './createAndEditEnvironment/uiSchema';

import createAndEditWorkspaceSchema from './createAndEditWorkspace/schema';
import createAndEditWorkspaceUiSchema from './createAndEditWorkspace/uiSchema';

import helmConnectionSchema from './helmConnection/schema';
import helmConnectionUiSchema from './helmConnection/uiSchema';

import importDesignSchema from './importDesign/schema';
import importDesignUiSchema from './importDesign/uiSchema';

import importFilterSchema from './importFilter/schema';
import importFilterUiSchema from './importFilter/uiSchema';

import publishCatalogItemSchema from './publishCatalogItem/schema';
import publishCatalogItemUiSchema from './publishCatalogItem/uiSchema';

export {
createAndEditEnvironmentSchema,
createAndEditEnvironmentUiSchema,
createAndEditWorkspaceSchema,
createAndEditWorkspaceUiSchema,
helmConnectionSchema,
helmConnectionUiSchema,
helpAndSupportModalSchema,
helpAndSupportModalUiSchema,
importDesignSchema,
importDesignUiSchema,
importFilterSchema,
importFilterUiSchema,
publishCatalogItemSchema,
publishCatalogItemUiSchema
};
51 changes: 51 additions & 0 deletions src/schemas/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# RJSF Schemas

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.

### What are RJSF Schemas?

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.

### How to Use RJSF Schemas

1. **Importing Schemas:**
Include the required schema in your React component by importing it. For example:

```javascript
import MyFormSchema from '@layer5/sistent';
```

1. **Rendering Forms:**
Integrate the schema into your component to render the form dynamically. Use already created generic RJSF components or use RJSF Form component directly.

```javascript
import { sampleSchema, sampleUiSchema } from '@layer5/sistent';
<Form schema={sampleSchema} uiSchema={sampleUiSchema} onSubmit={handleFormSubmission} />;
```

1. **Customization:**
Adjust the schema properties to tailor the form's appearance and behavior. Refer to the specific schema's documentation for customization options.

### File Conventions for Schemas

Follow a consistent file structure convention to enhance clarity and organization when adding new schema:

1. Use the same name as the schema for the directory.
1. Use CamelCase for multi-word schema names, e.g., UserRegistrationFormSchema.
1. Create two separate files, schema.tsx and uiSchema.tsx, to store both schemas separately.

### Naming Conventions for Schemas

Follow a consistent naming convention to enhance clarity and organization when adding new schema:

1. Use descriptive names that convey the purpose of the form.
1. CamelCase for multi-word schema names, e.g., UserRegistrationFormSchema.
1. Include "Schema" in the name to explicitly indicate that it's a schema, e.g., ProfileSettingsSchema.
1. Include "UiSchema" in the name to explicitly indicate that it's a UI schema, e.g., ProfileSettingsUiSchema.

### Custom Properties

In addition to the properties offered by the JSON schema, we have introduced the following custom properties that you can include in new schema:

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.
1. `x-encode-in-uri:` When set to true, this property enables RJSF to encode data in URI format and return it.

0 comments on commit 66bc556

Please sign in to comment.