-
-
Notifications
You must be signed in to change notification settings - Fork 368
Closed
Description
Is there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
我在一个项目中参照了ErrorLogger的实现,但是最终效果不太符合我预期,我也看到有人遇到了类似的问题#217
我希望能够增强ErrorLogger的全局异常处理能力:
- 能够自动处理类似
OnAfterRenderAsync等这种生命周期中触发的异常,这种异常会导致页面重新渲染,重新触发异常,不断循环 - 能够自动处理弹窗内的错误,弹窗出现错误也会导致不断循环
Describe the solution you'd like
经过一番折腾,我能够明白这是Blazor自身全局处理不够强导致,ErrorBoundary 基本不可能做到这种支持,最终我选择了一个妥协一点的方案:
- 检测是否触发循环错误渲染,如果是则采用默认的方案,进入错误页面,打断循环,
OnAfterRenderAsync这些生命周期中,应当尽量避免异常,或者手动处理异常,但是如果我们想要全局日志记录等,还是需要封装组件统一处理的支持 - 检测错误弹窗是否正确渲染出来
以下是我折腾出的代码:
public class ExceptionHandler : ErrorBoundaryBase
{
[Inject]
private IErrorBoundaryLogger? ErrorBoundaryLogger { get; set; }
private bool firstRender = true;
private bool showExceptionMessagePopover = false;
private int errorRenderCount = 0;
protected override async Task OnErrorAsync(Exception exception)
{
showExceptionMessagePopover = true;
errorRenderCount++;
await ErrorBoundaryLogger!.LogErrorAsync(exception);
}
protected override void OnAfterRender(bool firstRender)
{
this.firstRender = firstRender;
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
int sequence = 0;
if (CurrentException is null)
{
builder.AddContent(sequence++, ChildContent);
}
else if (ErrorContent is not null)
{
builder.AddContent(sequence++, ErrorContent(CurrentException));
}
else
{
if (firstRender || errorRenderCount> 2)
{
builder.OpenElement(sequence++, "div");
builder.AddAttribute(sequence++, "class", "blazor-error-boundary");
builder.CloseElement();
}
else
{
builder.AddContent(sequence++, ChildContent);
builder.OpenComponent<ExceptionMessagePopover>(3);
builder.AddComponentParameter(sequence++, "Open", showExceptionMessagePopover);
builder.AddComponentParameter(sequence++, "OpenChanged", EventCallback.Factory.Create<bool>(this, SetShowExceptionMessagePopover));
builder.AddComponentParameter(sequence++, "Exception", CurrentException);
builder.CloseComponent();
}
}
}
private void SetShowExceptionMessagePopover(bool value)
{
if (showExceptionMessagePopover && !value)//满足此条件,说明错误提示框成功渲染出来了,没有再触发其他异常,这里重置掉相关状态
{
errorRenderCount= 0;
Recover();
}
showExceptionMessagePopover = value;
}
}Additional context
No response
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request