Blazor WebAssembly全局捕获Razor组件异常并输出至浏览器控制台方案
Blazor WebAssembly 全局异常捕获方案
部署位置与Program.cs的可行性
完全可以把全局异常捕获逻辑放在Program.cs中,这是最推荐的位置——因为Program.cs是Blazor WebAssembly应用的启动入口,在这里配置的逻辑会全局生效,无需在多个文件中重复设置。
全局捕获实现方案
以下是一套完整的全局异常捕获配置,覆盖组件异常、异步任务异常、AppDomain级未捕获异常三类场景,所有逻辑集中在Program.cs中,配合App.razor的ErrorBoundary实现全链路捕获:
1. Program.cs 核心配置
var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<HeadOutlet>("head::after"); // 注册全局组件异常日志服务 builder.Services.AddSingleton<IErrorBoundaryLogger, GlobalErrorLogger>(); // 捕获未被观察到的异步任务异常 TaskScheduler.UnobservedTaskException += (sender, e) => { LogExceptionDetails(e.Exception, "未捕获异步任务异常"); e.SetObserved(); // 标记异常已处理,避免应用崩溃 }; // 捕获AppDomain级别的未捕获异常 AppDomain.CurrentDomain.UnhandledException += (sender, e) => { if (e.ExceptionObject is Exception ex) { LogExceptionDetails(ex, "AppDomain未捕获异常"); } }; var host = builder.Build(); await host.RunAsync(); // 统一异常日志输出方法 void LogExceptionDetails(Exception ex, string exceptionContext) { Console.WriteLine($"===== {exceptionContext} ====="); Console.WriteLine($"异常类型: {ex.GetType().FullName}"); Console.WriteLine($"异常消息: {ex.Message}"); Console.WriteLine($"异常位置:\n{ex.StackTrace}"); if (ex.InnerException != null) { Console.WriteLine("\n===== 内部异常 ====="); Console.WriteLine($"异常类型: {ex.InnerException.GetType().FullName}"); Console.WriteLine($"异常消息: {ex.InnerException.Message}"); Console.WriteLine($"异常位置:\n{ex.InnerException.StackTrace}"); } } // 自定义ErrorBoundary日志实现类 public class GlobalErrorLogger : IErrorBoundaryLogger { public ValueTask LogErrorAsync(Exception exception, ComponentErrorBoundary boundary) { LogExceptionDetails(exception, $"组件异常 (组件边界: {boundary.GetType().Name})"); return ValueTask.CompletedTask; } }
2. App.razor 配套配置
在App.razor中用ErrorBoundary包裹整个路由组件,确保所有页面组件的异常都能被捕获:
<ErrorBoundary> <ChildContent> <Router AppAssembly="@typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> <FocusOnNavigate RouteData="@routeData" Selector="h1" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <LayoutView Layout="@typeof(MainLayout)"> <p role="alert">Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </ChildContent> </ErrorBoundary>
关键说明
- 该方案实现一处配置全局生效:所有组件的同步/异步异常、未被等待的异步任务异常、顶级未捕获异常都会被捕获并输出到浏览器控制台。
- 日志内容包含异常类型、消息、堆栈跟踪(明确异常位置),以及内部异常信息,满足调试需求。
- 如果需要扩展(比如将异常上报到后端),只需修改
LogExceptionDetails方法即可,无需改动其他代码。
内容的提问来源于stack exchange,提问作者userxchange123
相关产品推荐
相关产品推荐

