import { useState } from "react"; import type { Meta, StoryObj } from "@storybook/react"; import { ErrorBoundary } from "./ErrorBoundary.component"; import { Button } from "../../Buttons/Button"; import { ErrorBanner } from "@components/Banners/DismissableBanner"; import { Text } from "@components/Typography/Text"; const meta: Meta = { title: "Feedback/ErrorBoundary", component: ErrorBoundary, parameters: { layout: "centered", }, argTypes: { fallback: { control: "text", description: `The fallback UI to display when an error is caught. This can be a React node or a function that receives the error and a reset function as arguments.`, }, resetKeys: { control: false, description: `An array of values that, when changed, will reset the error boundary's state.`, }, onError: { action: "error captured", description: `Callback function that is called when an error is caught. It receives the error and additional info as arguments.`, }, onReset: { action: "reset triggered", description: `Callback function that is called when the error boundary is reset.`, }, }, }; export default meta; type Story = StoryObj; const BuggyComponent = ({ shouldThrow }: { shouldThrow: boolean }) => { if (shouldThrow) { throw new Error("Something went wrong in the component!"); } return ( Everything is working fine! ); }; const BuggyCounter = () => { const [count, setCount] = useState(0); if (count > 3) { throw new Error("Count cannot be greater than 3!"); } return (

Count: {count}

); }; export const WithStaticFallback: Story = { render: () => { const [shouldThrow, setShouldThrow] = useState(false); return (
Oops! Something went wrong. Please try refreshing the page. } >
); }, }; export const WithFunctionFallback: Story = { render: () => { const [shouldThrow, setShouldThrow] = useState(false); return (
( Error: {error.message}
)} resetKeys={[shouldThrow]} onError={(error, errorInfo) => { console.log("Error caught:", error); console.log("Error info:", errorInfo); }} onReset={() => { console.log("Error boundary reset"); }} >
); }, }; export const WithResetKeys: Story = { render: () => { const [resetKey, setResetKey] = useState(0); const [userId, setUserId] = useState("user1"); return (

Reset key: {resetKey} | User ID: {userId}

Changing either value will reset the error boundary

Component crashed! Change the reset key or user ID above to recover. } resetKeys={[resetKey, userId]} onReset={() => { console.log("Error boundary reset due to resetKeys change"); }} >
); }, }; export const NestedErrorBoundaries: Story = { render: () => { const [outerError, setOuterError] = useState(false); const [innerError, setInnerError] = useState(false); return (
Outer error boundary caught an error! } >

Outer Component

Inner error boundary caught an error! } resetKeys={[innerError]} >

Inner Component

); }, };