or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-react.mdcss-styling.mddom-integration.mderror-boundaries.mdevent-system.mdindex.mdreact-hooks.mdrouting.mdserver-side-rendering.mdtesting-utilities.md
tile.json

error-boundaries.mddocs/

Error Boundaries

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.

Types

type info = {componentStack: string};

type params('error) = {
  error: 'error,
  info: info,
};

Component

[@react.component]
let make: (~children: React.element, ~fallback: params('error) => React.element) => React.element;

Usage Examples

Basic Error Boundary

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>
}

Production Error Boundary

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>
}

Nested Error Boundaries

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>
}

Error Boundary with Recovery

[@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>
}