blazor全局错误处理需分环境、类型、层级设计:开发阶段用内置错误ui和开发者异常页快速定位;生产环境通过自定义中间件与errorboundary实现服务端/客户端双层拦截,结合serilog结构化日志及上下文追踪,blazor server还需特别防护电路断开问题。

Blazor 的全局错误处理和日志记录不是“配个中间件就完事”,而是要分环境、分类型、分层级来设计。开发阶段靠框架内置机制快速定位,生产环境靠结构化日志+前端友好提示,而 Blazor Server 和 WebAssembly 的处理路径还不太一样。
开发阶段:用好框架自带的错误 UI 和开发者异常页
Blazor 项目模板默认在 MainLayout.razor 中嵌入了 <div id="blazor-error-ui"> 元素,配合 CSS 隐藏/显示逻辑,在发生未捕获异常时自动弹出底部提示条。这个 UI 在开发时会引导你打开浏览器控制台查看详细错误。
<p>对于服务器端(Blazor Server 或托管式 Web App),你还应确保启用 <strong>Developer Exception Page</strong>:</p>
<ul>
<li>在 <code>Program.cs 中调用 app.UseDeveloperExceptionPage()(仅限 IsDevelopment() 环境)
Accept: text/plain 请求时返回纯文本,便于 API 调试生产环境:统一拦截 + 结构化日志 + 友好降级
禁用开发者页面后,必须自己兜底。核心思路是两层拦截:
Modoer 是一款以本地分享,多功能的点评网站管理系统。采用 PHP+MYSQL 开发设计,开放全部源代码。因具有非凡的访问速度和卓越的负载能力而深受国内外朋友的喜爱。在升级前一定要备份好自己的原版本,特别是自己设计了模板和修改了代码的用户。Modoer多功能点评系统 v1.2.5 Build 20111220更新列表修正 安全漏洞和安全隐患增加 后台登陆和SQL错误记录日志修复 若干小BUG
-
服务端异常:添加自定义中间件(如
UseGlobalExceptionHandler),在try/catch中捕获HttpContext生命周期内的所有未处理异常;区分UserFriendlyException(业务异常,不记堆栈)和系统异常(记录完整日志,返回泛化消息) -
客户端组件异常:使用
<errorboundary></errorboundary>包裹关键区域。它会在子组件抛异常时隐藏内容、显示ErrorContent,并提供Recover()方法重试渲染——但注意:状态会丢失,表单类场景需配合@ref或状态管理缓存临时数据
日志记录:前后端一致、可追溯、带上下文
默认的 ILogger<t></t> 能满足基础输出,但生产环境建议升级为 Serilog:
- 配置方式简洁:
builder.Host.UseSerilog((ctx, cfg) => cfg.ReadFrom.Configuration(ctx.Configuration)) - 支持跨请求关联:用
LogContext.PushProperty("CorrelationId", ...)串联前后端日志 - Blazor WebAssembly 中日志默认输出到浏览器控制台;Server 模式下日志写入文件或中心化平台(如 Seq、Elasticsearch)
- 避免只记字符串——用消息模板(
MyLogger.LogError(ex, "Failed to load {UserId} profile"))保留结构化字段,方便后续查询
特别注意 Blazor Server 的“电路断开”问题
Blazor Server 依赖 SignalR 长连接(即“电路”)。一旦因未处理异常导致电路终止,用户无法继续交互,只能刷新页面重建连接。因此:
- 不要让异常穿透到 SignalR 层,尤其在
OnInitializedAsync、事件回调等生命周期方法中加必要防护 - 服务端日志必须包含电路 ID(
ConnectionId)和用户标识,便于快速定位故障会话 - 可在
OnError回调中监听电路异常,并触发主动通知或自动重连逻辑(需前端配合)
基本上就这些。不复杂但容易忽略的是环境适配和日志结构设计——开发时看着报错爽,上线后查不到根因才真头疼。









