The useErrors hook provides access to error state in an isomorphic error handling system. It implements the Props Context Layering pattern to work seamlessly across server and client boundaries, making it ideal for code highlighting and interactive demos that need robust error handling.
CodeErrorsContextconst { errors } = useErrors(props?);
| Parameter | Type | Description |
|---|---|---|
props | { errors?: Error[] } | Optional props containing fallback errors (typically from SSR) |
| Property | Type | Description |
|---|---|---|
errors | Error[] | undefined | Array of current errors (context errors take precedence over props) |
import { useErrors } from '@mui/internal-docs-infra/useErrors';
function DemoErrorHandler({ errors: propErrors }: { errors?: Error[] }) {
const { errors } = useErrors({ errors: propErrors });
if (!errors || errors.length === 0) {
return null; // No errors to display
}
return (
<div className="error-container">
<h4>Errors occurred:</h4>
{errors.map((error, index) => (
<div key={index} className="error-message">
{error.message}
</div>
))}
</div>
);
}
import { useErrors } from '@mui/internal-docs-infra/useErrors';
interface ErrorHandlerProps {
errors?: Error[]; // Props-based errors for SSR
}
function CodeErrorHandler({ errors }: ErrorHandlerProps) {
const { errors: resolvedErrors } = useErrors({ errors });
if (!resolvedErrors || resolvedErrors.length === 0) {
return <div>An error occurred, but details were not provided.</div>;
}
return (
<div className="code-error-handler">
<span>Error occurred when highlighting code: </span>
{resolvedErrors.map((error, index) => (
<div key={index} className="error-detail">
{error.message}
</div>
))}
</div>
);
}
import { useErrors } from '@mui/internal-docs-infra/useErrors';
import { CodeHighlighter } from '@mui/internal-docs-infra/CodeHighlighter';
function SafeCodeDemo({
code,
language,
errors: propErrors,
}: {
code: string;
language: string;
errors?: Error[];
}) {
const { errors } = useErrors({ errors: propErrors });
return (
<div className="code-demo">
{errors && errors.length > 0 ? (
<div className="error-fallback">
<p>Failed to render code demo:</p>
<ul>
{errors.map((error, index) => (
<li key={index}>{error.message}</li>
))}
</ul>
<details>
<summary>Raw Code</summary>
<pre>{code}</pre>
</details>
</div>
) : (
<CodeHighlighter code={code} language={language} />
)}
</div>
);
}
import { useErrors } from '@mui/internal-docs-infra/useErrors';
function FormattedErrorDisplay({ errors: propErrors }: { errors?: Error[] }) {
const { errors } = useErrors({ errors: propErrors });
if (!errors || errors.length === 0) {
return null;
}
const formatError = (error: Error) => {
// Extract useful information from error
const { message, name, stack } = error;
return {
title: name || 'Error',
description: message || 'An unknown error occurred',
details: stack?.split('\n').slice(0, 3).join('\n'), // First 3 lines of stack
};
};
return (
<div className="error-display">
{errors.map((error, index) => {
const formatted = formatError(error);
return (
<div key={index} className="error-item">
<h5>{formatted.title}</h5>
<p>{formatted.description}</p>
{formatted.details && (
<details>
<summary>Stack trace</summary>
<pre>{formatted.details}</pre>
</details>
)}
</div>
);
})}
</div>
);
}
This hook implements the Props Context Layering pattern for React Server Components:
useErrors({ errors }) automatically handles the precedence logicThe hook works across server-side and client-side environments:
CodeErrorsContext when processing occursIn isomorphic applications with code highlighting and live demos, errors can occur at different layers:
Without useErrors(): If error handlers only accept props, client-side errors appear as generic errors with no useful information.
With useErrors(): Both server and client errors are handled uniformly, providing detailed error information regardless of where the error occurred.
This follows the Props Context Layering pattern for isomorphic components:
// ❌ Props-only approach - breaks on client-side updates
function BadErrorHandler({ errors }: { errors?: Error[] }) {
// Only sees server-side errors passed as props
// Client-side errors are lost or appear generic
return errors ? <ErrorDisplay errors={errors} /> : null;
}
// ✅ Props Context Layering - works server and client
function GoodErrorHandler({ errors }: { errors?: Error[] }) {
const { errors: resolvedErrors } = useErrors({ errors });
// Hook implements: contextErrors || props.errors
// Server: uses props.errors (context undefined)
// Client: uses context.errors (takes precedence)
return resolvedErrors ? <ErrorDisplay errors={resolvedErrors} /> : null;
}
// 🎯 Server Component - no client code needed
function ServerOnlyErrorHandler({ errors }: { errors?: Error[] }) {
// When no client-side processing is needed, can stay server component
return errors ? <ErrorDisplay errors={errors} /> : null;
}
'use client';
import { useContext } from 'react';
import { CodeErrorsContext } from './ErrorsContext';
const useErrors = (props?: { errors?: Error[] }) => {
const contextErrors = useContext(CodeErrorsContext);
// Context takes precedence over props
return { errors: contextErrors?.errors || props?.errors };
};
const ErrorHandler = (props: { errors?: Error[] }) => {
const { errors } = useErrors(props);
return <ErrorDisplay errors={errors} />;
};
CodeErrorsContext.ProvideruseErrors({ errors }) provides latest state: Context errors override props automatically, ensuring users see the most relevant errorThis pattern ensures that users get detailed error information regardless of whether the error occurred during:
The hook handles the precedence logic internally, so error handler components simply pass their props and get back the most relevant errors.
The Props Context Layering pattern solves critical React Server Component challenges:
Without this pattern, you'd need separate components for:
Instead, useErrors({ errors }) provides a unified interface that automatically handles:
This ensures consistent error reporting and user experience while respecting React Server Component boundaries.
The hook connects to the CodeErrorsContext which is provided by components like CodeHighlighterClient:
import { CodeErrorsContext } from '@mui/internal-docs-infra/useErrors/ErrorsContext';
function ErrorProvider({ children, errors }: { children: React.ReactNode; errors?: Error[] }) {
const errorsContextValue = React.useMemo(() => ({ errors }), [errors]);
return (
<CodeErrorsContext.Provider value={errorsContextValue}>{children}</CodeErrorsContext.Provider>
);
}
useErrors() returns the latest error stateThe hook is commonly used with code highlighting components:
import { useErrors } from '@mui/internal-docs-infra/useErrors';
import { CodeHighlighterClient } from '@mui/internal-docs-infra/CodeHighlighter';
function CodeDemo() {
return (
<CodeHighlighterClient
/* ... props ... */
>
<CodeDemoContent />
</CodeHighlighterClient>
);
}
function CodeDemoContent() {
const { errors } = useErrors();
// Component has access to errors from CodeHighlighterClient context
return errors ? <ErrorDisplay /> : <LiveDemo />;
}
export interface CodeErrorsContext {
errors?: Error[];
}
export function useErrors(props?: { errors?: Error[] }): { errors?: Error[] } {
const context = useErrorsContext();
// Context errors take precedence over prop errors
const errors = context?.errors || props?.errors;
return { errors };
}
const { errors } = useErrors({ errors: propErrors });
// Always check if errors exist and have length
if (!errors || errors.length === 0) {
return <SuccessComponent />;
}
return <ErrorComponent errors={errors} />;
const { errors } = useErrors({ errors: propErrors });
if (errors && errors.length > 0) {
return (
<div>
<p>Something went wrong. Here's the raw content:</p>
<pre>{rawContent}</pre>
</div>
);
}
class CodeErrorBoundary extends React.Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}
render() {
if (this.state.hasError) {
return (
<CodeErrorsContext.Provider value={{ errors: [this.state.error] }}>
<ErrorFallback />
</CodeErrorsContext.Provider>
);
}
return this.props.children;
}
}
CodeHighlighter - Uses this hook for error displayCodeErrorHandler - Built-in error handler componentCodeErrorsContext - The underlying context