Skip to content

Commit

Permalink
feat: add error boundaries to smart components
Browse files Browse the repository at this point in the history
  • Loading branch information
a11rew committed Aug 21, 2024
1 parent 91286b5 commit bece82a
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { SmartComponentMap } from "@pantheon-systems/pcc-react-sdk/components";
import { serverSmartComponentMap } from "./server-components";
import MediaPreview from "./media-preview";
import { withSmartComponentErrorBoundary } from "./error-boundary";

const clientSmartComponentMap: SmartComponentMap = {
MEDIA_PREVIEW: {
...serverSmartComponentMap.MEDIA_PREVIEW,
reactComponent: MediaPreview,
reactComponent: withSmartComponentErrorBoundary(MediaPreview),
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { Component, Suspense } from "react";

interface Props {
children: React.ReactNode;
}

export class SmartComponentErrorBoundary extends Component<Props> {
state = {
hasError: false,
};

static getDerivedStateFromError() {
return { hasError: true };
}

render() {
if (this.state.hasError) {
return (
<div className="my-2 text-gray-400">
Something went wrong while rendering this smart component.
</div>
);
}

return this.props.children;
}
}

const SmartComponentSuspenseErrorBoundary = ({ children }: Props) => {
return (
<SmartComponentErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
</SmartComponentErrorBoundary>
);
};

export const withSmartComponentErrorBoundary =
// eslint-disable-next-line react/display-name
(Component: React.ComponentType) => (props: Record<string, unknown>) => (
<SmartComponentSuspenseErrorBoundary>
<Component {...props} />
</SmartComponentSuspenseErrorBoundary>
);

export default SmartComponentErrorBoundary;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { Component, Suspense } from "react";

interface Props {
children: React.ReactNode;
}

export class SmartComponentErrorBoundary extends Component<Props> {
state = {
hasError: false,
};

static getDerivedStateFromError() {
return { hasError: true };
}

render() {
if (this.state.hasError) {
return (
<div className="my-2 text-gray-400">
Something went wrong while rendering this smart component.
</div>
);
}

return this.props.children;
}
}

const SmartComponentSuspenseErrorBoundary = ({ children }: Props) => {
return (
<SmartComponentErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
</SmartComponentErrorBoundary>
);
};

export const withSmartComponentErrorBoundary =
// eslint-disable-next-line react/display-name
(Component: React.ComponentType) => (props: Record<string, unknown>) => (
<SmartComponentSuspenseErrorBoundary>
<Component {...props} />
</SmartComponentSuspenseErrorBoundary>
);

export default SmartComponentErrorBoundary;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
SmartComponentMap,
} from "@pantheon-systems/pcc-react-sdk/components";
import MediaPreview from "./media-preview";
import { withSmartComponentErrorBoundary } from "./error-boundary";

export const serverSmartComponentMap = {
MEDIA_PREVIEW: {
Expand All @@ -23,7 +24,7 @@ export const serverSmartComponentMap = {
export const clientSmartComponentMap: SmartComponentMap = {
MEDIA_PREVIEW: {
...serverSmartComponentMap.MEDIA_PREVIEW,
reactComponent: MediaPreview,
reactComponent: withSmartComponentErrorBoundary(MediaPreview),
},
};

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { Component, Suspense } from "react";

export class SmartComponentErrorBoundary extends Component {
state = {
hasError: false,
};

static getDerivedStateFromError() {
return { hasError: true };
}

render() {
if (this.state.hasError) {
return (
<div className="my-2 text-gray-400">
Something went wrong while rendering this smart component.
</div>
);
}

return this.props.children;
}
}

const SmartComponentSuspenseErrorBoundary = ({ children }) => {
return (
<SmartComponentErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
</SmartComponentErrorBoundary>
);
};

export const withSmartComponentErrorBoundary =
// eslint-disable-next-line react/display-name
(Component) => (props) => (
<SmartComponentSuspenseErrorBoundary>
<Component {...props} />
</SmartComponentSuspenseErrorBoundary>
);

export default SmartComponentErrorBoundary;
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withSmartComponentErrorBoundary } from "./error-boundary";
import MediaPreview from "./media-preview";

export const serverSmartComponentMap = {
Expand All @@ -19,7 +20,7 @@ export const serverSmartComponentMap = {
export const clientSmartComponentMap = {
MEDIA_PREVIEW: {
...serverSmartComponentMap.MEDIA_PREVIEW,
reactComponent: MediaPreview,
reactComponent: withSmartComponentErrorBoundary(MediaPreview),
},
};

0 comments on commit bece82a

Please sign in to comment.