7

For testing purpose, I would like to 'catch' any error occuring in my app and displaying it on the page (not in the console). For that purpose I discovered the ErrorBoundary component in the .Net 6 framework.

ErrorBoundaries doc from Microsoft

At first, I successfully tested this component inside a Bazor WebAssembly project.

Steps:

  • Create a newBlazor WebAssembly project
  • Create the component CustomErrorBoundary.razor (see code below)
  • In MainLayout.razor surround the @Body instruction with the component CustomErrorBoundary
  • In FetchData.razor throw an exception in the code (see below)

CustomErrorBoundary

    @inherits ErrorBoundary
    @if (CurrentException is null)
    {
        @ChildContent
    }
    else if (ErrorContent is not null)
    {
        @ErrorContent(CurrentException)
    }
    else
    {
        <div style="background-color: yellow; border: 2px dashed black; white-space: pre; font-family: consolas, monospace;">
            @foreach (var exception in receivedExceptions)
            {
                <div class="received-exception" style="background-color: rgba(255,255,255,0.3); margin: 0.5rem; padding: 0.5rem;">
                    @exception.Message
                </div>
            }
        </div>
    }

    @code {
        List<Exception> receivedExceptions = new();

        protected override Task OnErrorAsync(Exception exception)
        {
            receivedExceptions.Add(exception);
            return base.OnErrorAsync(exception);
        }

        public new void Recover()
        {
            receivedExceptions.Clear();
            base.Recover();
        }
    }

enter image description here

enter image description here

When testing this app and navigating in the FetchData, the error is thrown and displayed on the page.

enter image description here

So far so good. Now I would like to do the same but this time for a .NET Maui Blazor project.

Steps:

  • Create a newBlazor .NET Maui Blazor project
  • Add a the package Microsoft.AspNetCore.Components.Web to the project (to benefit from ErrorBoundary)
  • Restart Visual Studio (not mandatory)
  • Create the component CustomErrorBoundary.razor (see code above)
  • In MainLayout.razor surround the @Body instruction with the component CustomErrorBoundary
  • In WeatherForecastService.cs throw an exception in the code (see below)

enter image description here

Unfortunately, the project crash immeadiately when trying to start it.

enter image description here

So to be said simpler: it seems ErrorBoundary is not supported in a .NET Maui Blazor project.

<ErrorBoundary>
    @Body
</ErrorBoundary>

The simple code above does not works in Blazor Maui.

So I don't know if ErrorBoundary is compatible with .NET Maui Blazor ? If not, how to catch any errors inside a Blazor Maui project and display it on the page ?

Bronzato
  • 9,438
  • 29
  • 120
  • 212

3 Answers3

3

Trying to decipher the error, on first look, it seems that the type ErrorBoudary that you inherit needs a dependency that is not injected in your MAUI project.

I have found a post that seems to explain your issue Githubmemory on this issue Basically, you need to implement the interface and then register that new class as an available service.

Code of ErrorBoundary

code of IErrorBoundaryLogger

I would guess the Blazor Wasm implements this by default?

Shuryno
  • 532
  • 3
  • 13
2

I know this isn't an answer to this, and I hope this isn't bad form. I'm learning right now, I wanted to share a related code snippet in case anyone else wants to do this.

using the above example, and mudblazor. I made a custom error boundary component that displays the error in a snackbar popup.

CustomErrorBoundary.razor

@inherits ErrorBoundary
@inject ISnackbar Snackbar
@if (CurrentException is null)
{
    @ChildContent
}
else if (ErrorContent is not null)
{
    @ErrorContent(CurrentException)
}
else
{
    @ChildContent

        @foreach (var exception in receivedExceptions)
        {
            Snackbar.Add(@exception.Message, Severity.Error);
        }

    Recover();
}

@code {
    List<Exception> receivedExceptions = new();

    protected override Task OnErrorAsync(Exception exception)
    {
        receivedExceptions.Add(exception);
        return base.OnErrorAsync(exception);
    }

    public new void Recover()
    {
        receivedExceptions.Clear();
        base.Recover();
    }
}

MainLayout.razor

@inherits LayoutComponentBase
@inject ISnackbar Snackbar

<MudThemeProvider IsDarkMode="true"/>
<MudDialogProvider />
<MudSnackbarProvider />

<MudLayout>
    <MudAppBar>
        <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
    </MudAppBar>
    <MudDrawer @bind-Open="@_drawerOpen">
        <NavMenu/>
    </MudDrawer>
    <MudMainContent>
        <CustomErrorBoundary>
            @Body
        </CustomErrorBoundary>
    </MudMainContent>
</MudLayout>

@code {
    bool _drawerOpen = true;

    private void DrawerToggle()
    {
        _drawerOpen = !_drawerOpen;
    }
}
0

I am debating whether my answer only works because of MudBlazor or not, but since there is little feedback here, I will just throw it in. I am using the default ErrorBoundary, and it is working just fine for me. Maybe something has been updated in the past 9 months?

Here is my relevant code, in MainLayout.razor:

<MudLayout>
    <MudAppBar Elevation="0">
        @* Some random MudAppBar stuff... *@
    </MudAppBar>
    <MudMainContent>
        <MudContainer MaxWidth="MaxWidth.Large" Class="my-16 pt-16">
            <ErrorBoundary>
                <ChildContent>
                    @Body
                </ChildContent>
                <ErrorContent>
                    <p class="errorUI">An error has occured. Edit this content in MainLayout.razor</p>
                </ErrorContent>
            </ErrorBoundary>
        </MudContainer>
    </MudMainContent>
</MudLayout>

I am throwing an exception in a similar way as in the question, and the error content apperas :)

mathkid91
  • 659
  • 2
  • 10
  • 27