How to globally handle application level exceptions for client-side Blazor apps?
Blazor treats most unhandled exceptions as fatal to the circuit where they occur. If a circuit is terminated due to an unhandled exception, the user can only continue to interact with the app by reloading the page to create a new circuit.
Blazor projects are slow on the client-side because you have to download the entire dot net runtime along with the necessary DLL libraries on your browser. Additionally, Blazor apps have latency issues.
The Blazor WebAssembly hosting model has the following limitations: The app is restricted to the capabilities of the browser. Capable client hardware and software (for example, WebAssembly support) is required. Download size is larger, and apps take longer to load.
Blazor currently has two hosting models that are production-ready.
You can create a singleton service that handles the WriteLine event. This will be fired only on errors thanks to Console.SetError(this);
public class ExceptionNotificationService : TextWriter
{
private TextWriter _decorated;
public override Encoding Encoding => Encoding.UTF8;
public event EventHandler<string> OnException;
public ExceptionNotificationService()
{
_decorated = Console.Error;
Console.SetError(this);
}
public override void WriteLine(string value)
{
OnException?.Invoke(this, value);
_decorated.WriteLine(value);
}
}
You then add it to the Startup.cs file in the ConfigureServices function:
services.AddSingleton<ExceptionNotificationService>();
To use it you just subscribe to the OnException event in your main view.
Source
@Gerrit's answer is not up to date. Now you should use ILogger for handling unhandled exception.
My example
public interface IUnhandledExceptionSender
{
event EventHandler<Exception> UnhandledExceptionThrown;
}
public class UnhandledExceptionSender : ILogger, IUnhandledExceptionSender
{
public event EventHandler<Exception> UnhandledExceptionThrown;
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func<TState, Exception, string> formatter)
{
if (exception != null)
{
UnhandledExceptionThrown?.Invoke(this, exception);
}
}
}
Program.cs
var unhandledExceptionSender = new UnhandledExceptionSender();
var myLoggerProvider = new MyLoggerProvider(unhandledExceptionSender);
builder.Logging.AddProvider(myLoggerProvider);
builder.Services.AddSingleton<IUnhandledExceptionSender>(unhandledExceptionSender);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With