The .NET Stacks #57: ๐Ÿง Taking a look at Blazor Error Boundaries

This week, let's take a look at Blazor Error Boundaries and Minimal API improvements.

Dave Brock
Dave Brock

Good morning, everybody. I hope everyone has had a good last couple of weeks, as I took last week off to celebrate Independence Day here in the United States.

Here's what we have this week:

  • The big thing: Taking a look at Blazor Error Boundaries
  • The little things: .NET Foundation elections, Minimal API improvements, pining to help with OSS?
  • Last week in the .NET world

The big thing: Taking a look at Blazor Error Boundaries

This weekend, I finished writing a piece on Blazor error boundaries. It'll be published in a week or two, so here's a preview for you.

Looking at Blazor Server apps: when an unhandled exception occurs, Blazor Server treats it as a fatal error because the circuit hangs in an undefined state, which can potentially lead to usability or security problems. As a result, your app is as good as dead, loses its state, and your users are met with an undesirable An unhandled error has occurred message, with a link to reload the page.

This begs the question: if I get an unhandled exception from a single component, why should my entire app die? As a Blazor developer, you're left spending a lot of time hacking around this by putting try and catch blocks around every single method of your app, leading to performance issuesโ€”especially when thinking about cascading parameters. Blazor developers look longingly at React's Error Boundaries and wonder when we get to have nice things.

With .NET 6 Preview 4, you can. Inspired by Error Boundaries in React, it attempts to catch recoverable errors that can't permanently corrupt stateโ€”and like the React feature, it also renders a fallback UI. This capability won't catch all possible exceptions but most common scenarios such as the various lifecycle methods (like OnInitializedAsync, OnParametersSetAsync, and OnAfterRenderAsync , ย and rendering use cases with BuildRenderTree.

The new ErrorBoundary component provides a ChildContent fragment (what to display when all goes well), an ErrorContent fragment (what to display when it doesn't), and a CurrentException property so you can capture exception details.

Most importantly, the ErrorBoundary component allows you to call a Recover method, which resets the error boundary to a "non-errored state." By default, the component handles up to 100 errors through its MaximumErrorCount property. The Recover method does three things for you: it resets the component's error count to 0, clears the CurrentException and calls StateHasChanged. The StateHasChanged call notifies components that the state has changed and typically causes your component to be rerendered.

Here's an example:

@code {
    ErrorBoundary errorBoundary;

    protected override void OnParametersSet()
    {
        errorBoundary?.Recover();
    }
}

For another example, let's say you have a component that calls off to an API. Here, I'm getting a list of surfboards. I can wrap the data fetching in an ErrorBoundary.

<tbody>
   @foreach (var board in ShirtProductsList)
   {
        <ErrorBoundary @key="@board">
            <ChildContent>
                <tr>
                   <td>@board.Id</td>
                   <td>@board.Name</td>
                   <td>@board.Color</td>
                   <td>@board.Price</td>
                 </tr>   
             </ChildContent>
             <ErrorContent>
                 Sorry, I can't show @board.Id because of an internal error.
             </ErrorContent>
         </ErrorBoundary>        
     }
</tbody>

Blazor Error Boundaries is not meant to be a global exception handling mechanism for any and all unhandled errors you encounter in your apps. You should be able to log all uncaught exceptions using the ILogger interface.

While you can mark all your components with error boundaries and ignore exceptions, you should take a more nuanced approach to your application's error handling. Error Boundaries are meant for control over your specific component's unhandled exceptions and not a quick way to manage failures throughout your entire application. What do you think?


The little things: .NET Foundation elections, Minimal API improvements, pining to help with a project?

The .NET Foundation will be holding elections next month for two upcoming Board seats. If you've made it to the Elections page, you'll see my face as I'm on the Election Committee.

The .NET Foundation serves the general .NET community by promoting .NET in general, advocating .NET OSS, promoting .NET across a wider community of developers, supporting .NET community events, and offering administrative support to member projects. This is an organization that runs separately from Microsoft.

As a Board member, you'd help to run the .NET Foundation by deciding how the money is spent, decide which projects join the foundation, and much more. If you're interested in running for a seat, let me know and I'll get you started.


We've covered Minimal APIs in .NET 6 a time or two. Prioritizing functions over classes, it's a route to simple APIs that many call ".NET Express"โ€”I like the name because it describes getting right to the point and one of the inspirations.

The examples have mostly been a little "Hello World"-ish. ASP.NET Core architect David Fowler shows that it's coming along:

This Results class looks nice, especially if you aren't a fan of attributes for MVC controllers. I'm interested to see if it can be extended further, and the team is looking into it.

If you're looking to extend model binding by using a single request object, you'll have to wait as it won't make it into .NET 6 (but maybe .NET 7). You can bind directly from the JSON object, but manually dealing with route and query parameters might get a tad unwieldy.


If you're looking to help with some open-source, David Pine could use some help. David has a project called the Azure Cosmos DB Repository .NET SDK, which allows you to use the repository pattern to work with your Cosmos DB instances. It really helps to simplify working with CRUD behavior in Cosmos, especially if you're familiar with the IRepository<T> interface. I find it quite nice, and use it for one of my projects (and have written about it as well).

David is working on a Blazor book for O'Reillyโ€”if you've ever written a book or know someone who has, you won't be surprised to hear he'll need some help with the project. If you're interested in helping out, let him know.


๐ŸŒŽ Last week in the .NET world

๐Ÿ”ฅ The Top 3

๐Ÿ“… Community and events

๐ŸŒŽ Web development

๐Ÿฅ… The .NET platform

โ›… The cloud

๐Ÿ“” Languages

๐Ÿ”ง Tools

๐Ÿ— Design, testing, and best practices

๐ŸŽค Podcasts

๐ŸŽฅ Videos

.NET Stacks