Error State
Compound primitive for centered error messaging, recovery actions, and route-level failure surfaces.
Overview
ErrorState is the shared compound primitive for blocked or failed surfaces that need a clear title, explanation, and recovery action.
It is the low-level UI layer behind several broader platform patterns:
| Layer | Role |
|---|---|
ErrorState | Raw visual primitive for composing an error surface manually |
ErrorGuard | Runtime wrapper that maps an error object to a preset ErrorState |
Panel.ErrorGuard | Panel-tuned ErrorGuard with centered drawer spacing |
DataTable errorState | DataTable hook into ErrorGuard for collection-level failures |
This page documents the primitive layer. See the error-handling patterns page for when to use ErrorGuard, Panel.ErrorGuard, and DataTable error recovery.
Basic Composition
import { ErrorState } from '@fsai/shared-ui';
<ErrorState className="h-full min-h-full justify-center px-6 py-12">
<ErrorState.Icon />
<ErrorState.Title>Something went wrong</ErrorState.Title>
<ErrorState.Description>
There was a problem loading this content.
</ErrorState.Description>
<ErrorState.Actions>
<ErrorState.Action
role="button"
variant="primary"
onClick={handleRetry}
>
Retry
</ErrorState.Action>
</ErrorState.Actions>
</ErrorState>This is the standard full-surface composition used for route errors and feature-owned fallback screens.
Compound API
| Part | Purpose |
|---|---|
ErrorState | Root centered stack container |
ErrorState.Icon | Decorative icon treatment with concentric background rings |
ErrorState.Title | Primary failure heading |
ErrorState.Description | Supporting explanation text |
ErrorState.Actions | Horizontal action row |
ErrorState.Action | Shared Button-based recovery action |
Layout Patterns
ErrorState is intentionally minimal. The main layout control is className on the root.
Common layouts:
| Layout | Typical classes | Notes |
|---|---|---|
| Full page or route | h-full min-h-full justify-center px-6 py-12 | Centers the message in the available page shell |
| Panel body | min-h-full justify-center px-6 py-12 | This is what Panel.ErrorGuard standardizes |
| Scrollable table/list region | min-h-full flex-1 justify-start px-6 pt-32 pb-6 | Leaves space for toolbar and table chrome above |
| Compact message block | w-full | Useful when embedding only title and description in a custom layout |
Icons And Actions
ErrorState.Icon defaults to WarningTriangle.
Override it when the failure meaning is more specific, such as:
SearchMagnifyingGlassfor not-found statesLockLockedfor auth or permission problemsInfoSquarefor validation or request guidance
ErrorState.Action is just the shared Button API with sensible defaults:
variant="secondary"by defaultsize="md"by default- supports both
role="button"androle="link"
That means route-level recovery can navigate:
<ErrorState.Action role="link" href={routes.BASE} variant="primary">
Back Home
</ErrorState.Action>Props
ErrorState
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required. Error state content tree. |
className | string | — | Additional layout classes. |
| HTML div props | HTMLAttributes<HTMLDivElement> | — | Passed through to the root container. |
ErrorState.Icon
| Prop | Type | Default | Description |
|---|---|---|---|
icon | IconName | 'WarningTriangle' | Main error icon. |
className | string | — | Additional wrapper classes. |
ErrorState.Title
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required. Title content. |
className | string | — | Additional title classes. |
ErrorState.Description
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required. Description content. |
className | string | — | Additional description classes. |
ErrorState.Actions
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required. One or more actions. |
className | string | — | Additional action-row classes. |
ErrorState.Action
ErrorState.Action forwards shared ButtonProps.
Most common props:
| Prop | Type | Default | Description |
|---|---|---|---|
role | 'button' | 'link' | — | Required. Chooses interaction mode. |
variant | Button variant | 'secondary' | Visual emphasis for the action. |
size | Button size | 'md' | Shared button sizing. |
children | ReactNode | — | Required. Action label. |
onClick | () => void | — | Button action handler. |
href | string | — | Link destination when role="link". |
When Raw ErrorState Fits
Reach for raw composition when:
- the screen already knows the failure copy and actions
- the error surface is route-level or shell-level
- there is no runtime error object to classify
- the layout needs custom visual chrome around the error message
If you already have an error object and want shared presets like notFound, permissionDenied, or serverError, prefer ErrorGuard instead.
Brand Dashboard Usage
| Pattern | Path | Notes |
|---|---|---|
| Full-page fatal error | fsai/apps/brand-dashboard/src/pages/ErrorPage.tsx | Standard route-level fallback with reload action. |
| 404 page | fsai/apps/brand-dashboard/src/pages/NotFound/NotFound.tsx | Uses a more specific icon and navigation action. |
| Informational embedded message | fsai/apps/brand-dashboard/src/EmailActivity/EmailActivityDrawer.tsx | Existing usage without icon or actions inside a custom empty-state wrapper. |
Important Conventions
- Prefer
ErrorStatefor blocked or failed surfaces, not for ordinary empty content. - Keep actions recovery-oriented: retry, navigate, close, or go back.
- Let the surrounding surface decide spacing.
ErrorStateshould not hardcode page or panel sizing. - Use
ErrorGuardwhen the feature has a real runtime error object and should benefit from shared preset handling.
Guidelines
- Do use
ErrorStatefor centered error messaging with clear next actions - Do override the icon when the failure meaning is more specific than a generic warning
- Do use
role="link"on actions when recovery is navigation - Don't use raw
ErrorStatewhereErrorGuardorPanel.ErrorGuardalready expresses the pattern better - Don't treat
ErrorStateas the default empty-state primitive for non-error content