Code/ErrorBoundary.razor.cs
using System;
using System.Collections.Generic;
using Sandbox.Diagnostics;
using Sandbox.Razor;
namespace BetterUI;
/// <summary>
/// A panel that renders an error template when an error is encountered,
/// and provides an ID for the error boundary.
/// </summary>
/// <remarks>
/// Can be used to create custom error boundaries that can be used to
/// isolate errors in specific parts of the UI.
/// </remarks>
public partial class ErrorBoundary : Panel
{
/// <summary>
/// The ID of the error boundary.
/// </summary>
/// <remarks>
/// This can be used to identify the error boundary in logs and other
/// tools.
/// </remarks>
public string ErrorId { get; set; } = null!;
/// <summary>
/// A list of errors that have been encountered
/// </summary>
public List<Exception> Errors { get; } = new();
/// <summary>
/// The latest error that was encountered.
/// </summary>
/// <remarks>
/// This is null if no errors have been encountered.
/// </remarks>
public Exception? LatestError { get; private set; }
/// <summary>
/// The template to render for each error.
/// </summary>
/// <remarks>
/// The template is rendered with the error as the context.
/// </remarks>
public RenderFragment<Exception> OnError { get; set; } = null!;
/// <inheritdoc />
protected override void OnAfterTreeRender( bool firstTime )
{
Assert.NotNull( ErrorId, "ErrorBoundary must have an ErrorId" );
}
/// <summary>
/// Adds an error to the boundary.
/// </summary>
/// <param name="ex">The error to add.</param>
public void AddError( Exception ex )
{
LatestError = ex;
Errors.Add( ex );
}
/// <summary>
/// Clears all errors from the boundary.
/// </summary>
public void ClearErrors()
{
LatestError = null;
Errors.Clear();
}
/// <inheritdoc />
protected override int BuildHash() => HashCode.Combine( ErrorId, Errors.Count, LatestError );
}