Skip to content

Commit

Permalink
Add error boundaries to all hhd components
Browse files Browse the repository at this point in the history
  • Loading branch information
aarron-lee committed Jan 15, 2024
1 parent 005325b commit 825afa4
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 89 deletions.
41 changes: 41 additions & 0 deletions src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//@ts-nocheck
import { Component } from "react";
import { Alert, AlertIcon } from "@chakra-ui/react";

type PropsType = {
children: any;
title?: string;
};
type StateType = {
hasError: boolean;
title?: string;
};

class ErrorBoundary extends Component<PropsType, StateType> {
constructor(props) {
super(props);
this.state = { hasError: false, title: props?.title };
}

static getDerivedStateFromError(error) {
console.log(error);
return { hasError: true };
}

componentDidCatch(error, errorInfo) {
console.log(error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<Alert status="error">
<AlertIcon />
Error while trying to render {this.props.title}
</Alert>
);
}
return this.props.children;
}
}

export default ErrorBoundary;
153 changes: 85 additions & 68 deletions src/components/HhdComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { SettingType, SettingsType } from "../redux-modules/hhdSlice";
import HhdModesDropdown from "./HhdModesDropdown";
import HhdOptions from "./HhdOptions";
import HintsAccordion from "./HintsAccordion";
import ErrorBoundary from "./ErrorBoundary";

interface HhdComponentType extends SettingsType {
renderChild?: any;
Expand Down Expand Up @@ -87,9 +88,11 @@ const HhdComponent: FC<HhdComponentType> = ({
<HintsAccordion path={`${statePath}`} />
</Flex>
<Stack spacing="3">
{renderChild &&
typeof renderChild === "function" &&
renderChildren()}
<ErrorBoundary title={title}>
{renderChild &&
typeof renderChild === "function" &&
renderChildren()}
</ErrorBoundary>
</Stack>
</CardBody>
</>
Expand All @@ -99,19 +102,21 @@ const HhdComponent: FC<HhdComponentType> = ({
// specially handle xinput child
const value = get(state, `${statePath}.mode`, defaultValue);
return (
<HhdModesDropdown
modes={modes}
defaultValue={defaultValue}
selectedValue={value}
title={title}
depth={depth}
state={state}
statePath={statePath}
updateState={updateState}
hint={hint}
renderChild={renderChild}
updating={updating}
/>
<ErrorBoundary title={title}>
<HhdModesDropdown
modes={modes}
defaultValue={defaultValue}
selectedValue={value}
title={title}
depth={depth}
state={state}
statePath={statePath}
updateState={updateState}
hint={hint}
renderChild={renderChild}
updating={updating}
/>
</ErrorBoundary>
);
}

Expand All @@ -125,25 +130,27 @@ const HhdComponent: FC<HhdComponentType> = ({

return (
<div>
<FormLabel htmlFor={`${statePath}`}>{title}</FormLabel>
<NumberInput
id={`${statePath}`}
value={value}
onChange={(value) => {
if (updating) {
return;
}
return updateState(`${statePath}`, Number(value));
}}
min={min}
max={max}
>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<ErrorBoundary title={title}>
<FormLabel htmlFor={`${statePath}`}>{title}</FormLabel>
<NumberInput
id={`${statePath}`}
value={value}
onChange={(value) => {
if (updating) {
return;
}
return updateState(`${statePath}`, Number(value));
}}
min={min}
max={max}
>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
</ErrorBoundary>
</div>
);
}
Expand All @@ -153,18 +160,20 @@ const HhdComponent: FC<HhdComponentType> = ({
const checked = get(state, `${statePath}`, defaultValue);
return (
<Flex flexDirection="row">
<FormLabel htmlFor={`${statePath}`}>{title}</FormLabel>
<Box flexGrow="1"></Box>
<Checkbox
id={`${statePath}`}
isChecked={Boolean(checked)}
onChange={(e) => {
if (updating) {
return;
}
return updateState(`${statePath}`, e.target.checked);
}}
/>
<ErrorBoundary title={title}>
<FormLabel htmlFor={`${statePath}`}>{title}</FormLabel>
<Box flexGrow="1"></Box>
<Checkbox
id={`${statePath}`}
isChecked={Boolean(checked)}
onChange={(e) => {
if (updating) {
return;
}
return updateState(`${statePath}`, e.target.checked);
}}
/>
</ErrorBoundary>
</Flex>
);
}
Expand All @@ -175,23 +184,25 @@ const HhdComponent: FC<HhdComponentType> = ({

return (
<Flex flexDirection="column">
<FormLabel htmlFor={`${statePath}`}>{title}</FormLabel>
<Select
id={`${statePath}`}
onChange={(e) => {
if (updating) {
return;
}
if (type === "discrete") {
// discrete is always numeric
return updateState(`${statePath}`, Number(e.target.value));
}
return updateState(`${statePath}`, e.target.value);
}}
value={value}
>
<HhdOptions type={type} options={options} />
</Select>
<ErrorBoundary title={title}>
<FormLabel htmlFor={`${statePath}`}>{title}</FormLabel>
<Select
id={`${statePath}`}
onChange={(e) => {
if (updating) {
return;
}
if (type === "discrete") {
// discrete is always numeric
return updateState(`${statePath}`, Number(e.target.value));
}
return updateState(`${statePath}`, e.target.value);
}}
value={value}
>
<HhdOptions type={type} options={options} />
</Select>
</ErrorBoundary>
</Flex>
);
}
Expand All @@ -205,15 +216,21 @@ const HhdComponent: FC<HhdComponentType> = ({
}

return (
<Code padding="1rem">
{title} - {value}
</Code>
<ErrorBoundary title={title}>
<Code padding="1rem">
{title} - {value}
</Code>
</ErrorBoundary>
);
}

if (type === "action" && title) {
return (
<Button onClick={() => updateState(`${statePath}`, true)}>{title}</Button>
<ErrorBoundary title={title}>
<Button onClick={() => updateState(`${statePath}`, true)}>
{title}
</Button>
</ErrorBoundary>
);
}

Expand Down
45 changes: 24 additions & 21 deletions src/components/HhdState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import HhdComponent, { renderChild } from "./HhdComponent";
import { useSetHhdState } from "../hooks/controller";
import { Card } from "@chakra-ui/react";
import ErrorBoundary from "./ErrorBoundary";

const HhdState = () => {
const state = useSelector(selectHhdSettingsState);
Expand All @@ -24,28 +25,30 @@ const HhdState = () => {
}}
backgroundColor={"white.50"}
>
{Object.entries(settings).map(([topLevelStr, plugins], topIdx) => {
return (
<div key={topIdx}>
{Object.keys(plugins).map((pluginName, idx) => {
const plugin = plugins[pluginName] as SettingsType;
const statePath = `${topLevelStr}.${pluginName}`;
<ErrorBoundary>
{Object.entries(settings).map(([topLevelStr, plugins], topIdx) => {
return (
<div key={topIdx}>
{Object.keys(plugins).map((pluginName, idx) => {
const plugin = plugins[pluginName] as SettingsType;
const statePath = `${topLevelStr}.${pluginName}`;

return (
<HhdComponent
key={`${statePath}${topIdx}${idx}`}
{...plugin}
state={state}
childName={pluginName}
renderChild={renderChild}
statePath={statePath}
updateState={setState}
/>
);
})}
</div>
);
})}
return (
<HhdComponent
key={`${statePath}${topIdx}${idx}`}
{...plugin}
state={state}
childName={pluginName}
renderChild={renderChild}
statePath={statePath}
updateState={setState}
/>
);
})}
</div>
);
})}
</ErrorBoundary>
</Card>
);
};
Expand Down

0 comments on commit 825afa4

Please sign in to comment.