Skip to content

Extras

ErrorBoundary

Bit.BlazorUI.Extras

BitErrorBoundary wraps a part of the page and catches whatever the components inside it throw, rendering a themed, recoverable error UI in their place instead of letting one failure tear the whole app down. It builds on Blazor's own ErrorBoundary, adding a complete default UI (icon, title, message, optional exception details and Refresh / Home / Recover actions), templates for every part of it, logging, callbacks, automatic recovery on navigation or on a change of state, and a way in for the exceptions the renderer never sees.

Notes

To use this component, you need to install the Bit.BlazorUI.Extras(opens in a new tab) nuget package, as described in the Optional steps of the Getting started page.

A boundary catches what the components inside it throw while they render, while their lifecycle methods run, and while they handle an event. It does not catch what never reaches the renderer - a fire-and-forget task, a timer callback, a JS interop callback - nor anything thrown outside it. Use Capture for those, and scope boundaries narrowly: the closer a boundary sits to what failed, the more of the page survives the failure.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

Wrap anything that can fail. While nothing has thrown, the boundary renders its content and no element of its own; the first exception replaces that content with the default error UI - the illustration, the title, and a footer offering to reload the page, to leave for the home page, or to simply try rendering the content again.

Title & message

Title replaces the default heading and Message adds a line under it. The title says that something broke; the message is where whoever is looking at the screen is told what it means for them and what to do next, which is the difference between an error page that reads as an apology and one that reads as an instruction.

Exception details

ShowException renders the exception's full text - message, type and stack trace - under the title, in a block that scrolls and takes the keyboard focus so it stays reachable. ShowCopyButton puts that same text on the clipboard instead, which is what turns a screenshot of an error into something searchable in a bug report; the button says CopiedText for a moment afterwards, since a copy leaves nothing else on the screen to show for itself. Both are what a developer needs while building and internal detail in front of a user once the app is deployed, so both are off by default and belong behind an environment check.

Icon

The built-in illustration is drawn in the theme's error color, so it re-skins with everything else. IconName swaps it for a glyph of the Fluent icon set, IconTemplate for markup of your own, and HideIcon drops it altogether - which is what a boundary around a small region wants, where a 64 pixel illustration is louder than whatever failed.

Buttons

The three default actions are independent. Refresh reloads the page in the browser, Home navigates to HomeUrl (the site root unless you name another), and Recover clears the error and renders the content again - so it only helps once whatever threw has been put right, which is why it is the one to hide when nothing about the failure will have changed by the time the reader clicks it. Each has its own text parameter and its own Hide...Button, the Copy button joins them in the same row wherever ShowCopyButton is set, and AdditionalButtons appends to the row rather than replacing it.

Footer

Footer replaces the whole row of default buttons while keeping the icon, the title and the message of the default UI - the middle ground between accepting the built-in actions and writing the error UI from scratch. What it replaces is the buttons and not the row: it is rendered in the same footer element they were laid out in, so it keeps their wrapping row and is reached by Classes.Footer and Styles.Footer exactly as they are. A boundary that sets it never renders AdditionalButtons.

Error template

ErrorTemplate replaces the error UI outright and is handed a context carrying the exception along with the boundary's own Recover, Refresh and GoHome actions, so a retry button is one @context.Recover away with no component reference to wire up. The inherited ErrorContent template still works and receives the exception alone; where both are set, ErrorTemplate wins.

Events

OnError runs before the error UI is rendered, which is where the exception is reported to whatever collects them, and OnRecover runs on every route back out of the errored state - the Recover button, the Recover method, RecoverKeys and RecoverOnNavigation alike. Which of them it was arrives as a BitErrorBoundaryRecoverReason, since a reader who asked to try again is waiting for something to happen while a boundary that cleared itself is not. The boundary also logs through the app's IErrorBoundaryLogger, exactly as Blazor's own boundary does; NoLogging turns that off where OnError already reports the exception elsewhere.


Caught: 0  |  Recovered: 0  |  Last error: -  |  Last recovery: -

Capture

A boundary only ever sees what the renderer routes to it, which leaves out everything thrown where nothing is awaiting it - a fire-and-forget task, a timer, a JS interop callback, an exception a page caught itself and wants shown. Capture hands the boundary one of those and puts it into exactly the state a caught exception would: logged, reported through OnError, counted against MaximumErrorCount and rendered. Reach the boundary through @ref, or - since it cascades itself to its content - through a cascading parameter from anywhere inside it, which is the Blazor counterpart of React's showBoundary. Use CaptureAsync off the renderer's thread.

Recover keys

An errored boundary keeps showing its error UI until something clears it, and what makes the content worth rendering again is usually a change somewhere else - a different record selected, a filter reset, a retry counter bumped. List those values in RecoverKeys and the boundary recovers itself the moment any of them differs from what it last saw, which is React's resetKeys without the component reference.




Selected record: 1

Recover on navigation

A boundary wrapping the body of a layout outlives the page that threw, so without help its error UI stays on screen wherever the reader goes next. RecoverOnNavigation clears it on the next location change, which is what makes a single app-wide boundary usable. A narrowly scoped boundary has no use for it - it is torn down with the page it belongs to.



Accessibility

The error UI is an assertive live region with the alert role, so a screen reader announces it where it appeared - the content it replaced is gone and nothing else on the page says so. AutoFocus also carries the reader to it, which is what a boundary around a whole page wants, where whatever had the focus went with the content. The exception block scrolls and holds nothing that can take the focus, so it takes it itself and is named as a region by ExceptionLabel; an empty label drops the name and the role with it. Every one of the underlying attributes - role, aria-live, aria-atomic, tabindex - can be written as a plain HTML attribute on the boundary, and what you write wins over what the boundary would have written.

External Icons

The icon also takes a BitIconInfo, which renders whatever CSS classes an external library needs. Use the Fa, Bi and Css helpers, or pass the classes as a plain string.

Style & Class

Style and Class land on the root of the error UI, and Styles and Classes reach each part of it by name - the icon, the title, the message, the exception block, the footer and each of its buttons. None of them touch the boundary's own content: while nothing has been caught there is no element of the boundary's to style.

RTL

Use BitErrorBoundary in right-to-left (RTL).

API

Every parameter, public member, sub-class and enum this component exposes.

BitErrorBoundary parameters

Name Type Default value Description
AdditionalButtons RenderFragment? null The extra content of the footer of the boundary's default error UI, rendered after the Refresh, Home and Recover buttons. A boundary that sets Footer never renders it.
AutoFocus bool false Moves the browser focus to the error UI as it appears, once per error. An error UI drawn by ErrorTemplate or ErrorContent has no element of the boundary's to move it to.
Body RenderFragment? null Alias of the ChildContent.
ChildContent RenderFragment? null The content the boundary renders and watches over while it has caught nothing.
Class string? null The CSS class of the root element of the boundary's error UI.
Classes BitErrorBoundaryClassStyles? null Custom CSS classes for different parts of the boundary's default error UI.
CopiedText string? null The text the Copy button carries while what it copied is still on the clipboard. Defaults to "Copied".
CopyText string? null The text of the Copy button. Defaults to "Copy details".
Dir BitDir? null The text directionality of the boundary's error UI.
ErrorContent RenderFragment<Exception>? null The inherited template of the error UI, receiving the caught exception alone. ErrorTemplate takes precedence over it.
ErrorTemplate RenderFragment<BitErrorBoundaryContext>? null The template of the error UI, receiving the caught exception along with the boundary's own Recover, Refresh and GoHome actions.
ExceptionLabel string? null The accessible name of the exception details block rendered by ShowException. Defaults to "Exception details", and an empty value drops the name and the region role with it.
Footer RenderFragment? null The footer content of the boundary, replacing the default Refresh, Home and Recover buttons while keeping the footer element they are laid out in.
HideHomeButton bool false Prevents rendering the Home button of the default error UI.
HideIcon bool false Prevents rendering the icon of the default error UI.
HideRecoverButton bool false Prevents rendering the Recover button of the default error UI.
HideRefreshButton bool false Prevents rendering the Refresh button of the default error UI.
HomeText string? null The text of the Home button.
HomeUrl string? null The url of the home page for the Home button. Defaults to the site root.
HtmlAttributes Dictionary<string, object>? null The HTML attributes to be applied to the root element of the boundary's error UI.
Icon BitIconInfo? null The icon to display using custom CSS classes for external icon libraries. Takes precedence over IconName when both are set.
IconName string? null The name of the icon to render in place of the built-in illustration.
IconTemplate RenderFragment? null The template of the icon, replacing both the built-in illustration and IconName.
Id string? null The id of the root element of the boundary's error UI.
MaximumErrorCount int 100 The number of errors this boundary handles before it stops absorbing them and lets the next one through as fatal. Recovering resets the count.
Message string? null The message rendered under the title of the default error UI. Nothing is rendered while it has no value.
NoLogging bool false Prevents the boundary from logging the caught exception through the app's IErrorBoundaryLogger.
OnError EventCallback<Exception> The callback for when an error gets caught by the boundary, called before the error UI is rendered.
OnRecover EventCallback<BitErrorBoundaryRecoverReason> The callback for when the boundary leaves its errored state, receiving which of the routes back out of it was taken.
RecoverKeys IEnumerable<object?>? null The values that recover the boundary as they change.
RecoverOnNavigation bool false Recovers the boundary when the reader navigates to another location.
RecoverText string? null The text of the Recover button.
RefreshText string? null The text of the Refresh button.
ShowCopyButton bool false Renders a Copy button in the footer of the default error UI, putting the exception's full text on the clipboard.
ShowException bool false Whether the actual exception information should be shown or not.
Style string? null The CSS style of the root element of the boundary's error UI.
Styles BitErrorBoundaryClassStyles? null Custom CSS styles for different parts of the boundary's default error UI.
Title string? null The header title of the boundary. Defaults to "Oops, Something went wrong...".

BitErrorBoundary public members

Name Type Default value Description
CaughtException Exception? null The exception the boundary is currently showing, or null while it has caught nothing.
Capture void Capture(Exception exception) Hands the boundary an exception that never passed through the renderer, putting it into exactly the state a caught one would. Call it on the renderer's synchronization context.
CaptureAsync Task CaptureAsync(Exception exception) Capture from a thread that is not the renderer's.
Recover void Recover() Clears the error and renders the boundary's content again, raising OnRecover. Never call it from rendering logic.
Refresh void Refresh() Reloads the current page in the browser, which is what the default UI's Refresh button does.
GoHome void GoHome() Navigates to HomeUrl, which is what the default UI's Home button does.

BitComponentBase parameters

Name Type Default value Description
AriaLabel string? null Gets or sets the accessible label for the component, used by assistive technologies.
Class string? null Gets or sets the CSS class name(s) to apply to the rendered element.
Dir BitDir? null Gets or sets the text directionality for the component's content.
ForceAnimation bool false Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested.
HtmlAttributes Dictionary<string, object> new Dictionary<string, object>() Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters.
Id string? null Gets or sets the unique identifier for the component's root element.
IsEnabled bool true Gets or sets a value indicating whether the component is enabled and can respond to user interaction.
Style string? null Gets or sets the CSS style string to apply to the rendered element.
TabIndex string? null Gets or sets the tab order index for the component when navigating with the keyboard.
Visibility BitVisibility BitVisibility.Visible Gets or sets the visibility state (visible, hidden, or collapsed) of the component.

BitComponentBase public members

Name Type Default value Description
UniqueId Guid Guid.NewGuid() Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed.
RootElement ElementReference Gets the reference to the root HTML element associated with this component.

BitErrorBoundaryClassStyles properties

Nothing here reaches the boundary's own content: while no error has been caught the boundary renders its children and no element of its own.

Name Type Default value Description
Root string? null Custom CSS classes/styles for the root element of the BitErrorBoundary's error UI.
Icon string? null Custom CSS classes/styles for the icon of the BitErrorBoundary.
Title string? null Custom CSS classes/styles for the title of the BitErrorBoundary.
Message string? null Custom CSS classes/styles for the message of the BitErrorBoundary.
Exception string? null Custom CSS classes/styles for the exception details block of the BitErrorBoundary.
Footer string? null Custom CSS classes/styles for the footer of the BitErrorBoundary, which holds a replaced Footer exactly as it holds the default buttons.
RefreshButton BitButtonClassStyles? null Custom CSS classes/styles for the Refresh button of the BitErrorBoundary.
HomeButton BitButtonClassStyles? null Custom CSS classes/styles for the Home button of the BitErrorBoundary.
RecoverButton BitButtonClassStyles? null Custom CSS classes/styles for the Recover button of the BitErrorBoundary.
CopyButton BitButtonClassStyles? null Custom CSS classes/styles for the Copy button of the BitErrorBoundary.

BitErrorBoundaryContext properties

What an ErrorTemplate is handed: the exception that was caught and the three ways out of it that the boundary's own error UI offers.

Name Type Default value Description
Exception Exception The exception the boundary caught.
Recover Action Clears the error and renders the boundary's content again, exactly like the default UI's Recover button.
Refresh Action Reloads the current page in the browser, exactly like the default UI's Refresh button.
GoHome Action Navigates to HomeUrl, exactly like the default UI's Home button.

BitErrorBoundaryRecoverReason enum

Name Value Description
Manual 0 The Recover button of the default error UI, the Recover action of an ErrorTemplate's context, or a call to the Recover method.
Keys 1 One of the values of RecoverKeys differed from what the boundary last saw.
Navigation 2 The reader navigated to another location while RecoverOnNavigation was set.

BitVisibility enum

Name Value Description
Visible 0 The content of the component is visible.
Hidden 1 The content of the component is hidden, but the space it takes on the page remains (visibility:hidden).
Collapsed 2 The component is hidden (display:none).

BitDir enum

Name Value Description
Ltr 0 Ltr (left to right) is to be used for languages that are written from the left to the right (like English).
Rtl 1 Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic).
Auto 2 Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element.

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.