Class-based error boundary component for catching and handling React errors. Provides fallback UI rendering and error information access.
Note: This module will likely be deprecated when React provides functional component error boundaries.
type info = {componentStack: string};
type params('error) = {
error: 'error,
info: info,
};[@react.component]
let make: (~children: React.element, ~fallback: params('error) => React.element) => React.element;let errorFallback = (params) => {
<div style={ReactDOMStyle.make(~color="red", ~padding="20px", ())}>
<h2> {React.string("Something went wrong!")} </h2>
<details>
<summary> {React.string("Error details")} </summary>
<pre> {React.string(params.error->Js.String.make)} </pre>
<pre> {React.string(params.info.componentStack)} </pre>
</details>
</div>
};
[@react.component]
let make = (~children) => {
<ReasonReactErrorBoundary fallback=errorFallback>
{children}
</ReasonReactErrorBoundary>
}let productionErrorFallback = (params) => {
/* Log error to monitoring service */
logError(params.error, params.info.componentStack);
<div className="error-boundary">
<h2> {React.string("We're sorry, something went wrong.")} </h2>
<p> {React.string("Please refresh the page or try again later.")} </p>
<button onClick={_ => Dom.location->Dom.Location.reload}>
{React.string("Refresh Page")}
</button>
</div>
};
[@react.component]
let make = (~children) => {
<ReasonReactErrorBoundary fallback=productionErrorFallback>
{children}
</ReasonReactErrorBoundary>
}let globalErrorFallback = (params) => {
<div className="global-error">
<h1> {React.string("Application Error")} </h1>
<p> {React.string("A critical error occurred. Please contact support.")} </p>
</div>
};
let sectionErrorFallback = (params) => {
<div className="section-error">
<h3> {React.string("This section failed to load")} </h3>
<button onClick={_ => Dom.location->Dom.Location.reload}>
{React.string("Retry")}
</button>
</div>
};
[@react.component]
let make = () => {
<ReasonReactErrorBoundary fallback=globalErrorFallback>
<div>
<Header />
<main>
<ReasonReactErrorBoundary fallback=sectionErrorFallback>
<UserDashboard />
</ReasonReactErrorBoundary>
<ReasonReactErrorBoundary fallback=sectionErrorFallback>
<RecentActivity />
</ReasonReactErrorBoundary>
</main>
<Footer />
</div>
</ReasonReactErrorBoundary>
}[@react.component]
let make = (~children) => {
let (hasError, setHasError) = React.useState(() => false);
let (errorCount, setErrorCount) = React.useState(() => 0);
let retry = () => {
setHasError(_ => false);
setErrorCount(count => count + 1);
};
let fallback = (params) => {
React.useEffect1(() => {
setHasError(_ => true);
None;
}, [|params.error|]);
<div className="error-boundary-with-retry">
<h3> {React.string("Something went wrong")} </h3>
<p> {React.string("Error count: " ++ string_of_int(errorCount))} </p>
{errorCount < 3
? <button onClick={_ => retry()}>
{React.string("Try Again")}
</button>
: <div>
<p> {React.string("Too many errors. Please refresh the page.")} </p>
<button onClick={_ => Dom.location->Dom.Location.reload}>
{React.string("Refresh")}
</button>
</div>
}
</div>
};
/* Reset error boundary when children change */
let key = hasError ? "error-" ++ string_of_int(errorCount) : "normal";
<ReasonReactErrorBoundary key fallback>
{children}
</ReasonReactErrorBoundary>
}