I'm on a search for handling business rule validation at a more global scale. Any BusinessRuleException thrown should result in a notification to the user. I thought of using the new ErrorBoundary component as a base for my own class but it is troublesome. The implementation below works but it refreshes the whole screen on each error which is not nice. Maybe my approach is not the best solution. Any input is appreciated. Here's my solution so far.
My own Boundary class:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;
using MyProjects.Core.Exceptions;
using Radzen;
namespace MyProjects.Infrastructure
{
public class MyProjectsBusinessRuleErrors : ErrorBoundary
{
[Inject]
private NotificationService _notificationService { get; set; } = default!;
protected override void OnInitialized()
{
base.OnInitialized();
}
protected override Task OnErrorAsync(Exception exception)
{
if(exception is BusinessRuleException)
{
_notificationService.Notify(NotificationSeverity.Error, exception.Message);
return Task.CompletedTask;
}
return base.OnErrorAsync(exception);
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
if (CurrentException is null || CurrentException is BusinessRuleException)
{
builder.AddContent(0, ChildContent);
}
else
{
base.BuildRenderTree(builder);
}
}
}
}
and the MainLayout.razor:
@inherits LayoutComponentBase
@using MyProjects.Infrastructure
<RadzenTooltip/>
<RadzenDialog/>
<RadzenNotification/>
<PageTitle>MyProjects</PageTitle>
<div class="page">
<main>
<article class="content px-4">
<MyProjectsBusinessRuleErrors @ref="errorBoundary">
<ChildContent>
@Body
</ChildContent>
<ErrorContent>
An error has occured
</ErrorContent>
</MyProjectsBusinessRuleErrors>
</article>
</main>
</div>
And code behind:
using MyProjects.Infrastructure;
namespace MyProjects.Shared
{
public partial class MainLayout
{
MyProjectsBusinessRuleErrors? errorBoundary { get; set; }
protected override void OnParametersSet()
{
errorBoundary?.Recover();
base.OnParametersSet();
}
}
}