Skip to content

Commit 89250df

Browse files
committed
refactor: 重构 ErrorLogger 组件
1 parent 4309091 commit 89250df

File tree

2 files changed

+143
-125
lines changed

2 files changed

+143
-125
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
5+
6+
using Microsoft.AspNetCore.Components.Rendering;
7+
using Microsoft.Extensions.Configuration;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace BootstrapBlazor.Components;
11+
12+
/// <summary>
13+
/// 内部使用 自定义异常组件
14+
/// </summary>
15+
class BootstrapBlazorErrorBoundary : ErrorBoundaryBase
16+
{
17+
[Inject]
18+
[NotNull]
19+
private ILogger<ErrorLogger>? Logger { get; set; }
20+
21+
[Inject]
22+
[NotNull]
23+
private IConfiguration? Configuration { get; set; }
24+
25+
[Inject]
26+
[NotNull]
27+
private ToastService? ToastService { get; set; }
28+
29+
/// <summary>
30+
/// 获得/设置 自定义错误处理回调方法
31+
/// </summary>
32+
[Parameter]
33+
public Func<ILogger, Exception, Task>? OnErrorHandleAsync { get; set; }
34+
35+
/// <summary>
36+
/// 获得/设置 是否显示弹窗 默认 true 显示
37+
/// </summary>
38+
[Parameter]
39+
public bool ShowToast { get; set; } = true;
40+
41+
/// <summary>
42+
/// 获得/设置 Toast 弹窗标题
43+
/// </summary>
44+
[Parameter]
45+
[NotNull]
46+
public string? ToastTitle { get; set; }
47+
48+
/// <summary>
49+
/// <inheritdoc/>
50+
/// </summary>
51+
/// <param name="exception"></param>
52+
/// <returns></returns>
53+
/// <exception cref="NotImplementedException"></exception>
54+
protected override async Task OnErrorAsync(Exception exception)
55+
{
56+
// 由框架调用
57+
if (OnErrorHandleAsync != null)
58+
{
59+
await OnErrorHandleAsync(Logger, exception);
60+
}
61+
else
62+
{
63+
if (ShowToast)
64+
{
65+
await ToastService.Error(ToastTitle, exception.Message);
66+
}
67+
68+
Logger.LogError(exception, "{BootstrapBlazorErrorBoundary} {OnErrorAsync} log this error", nameof(BootstrapBlazorErrorBoundary), nameof(OnErrorAsync));
69+
}
70+
}
71+
72+
/// <summary>
73+
/// <inheritdoc/>
74+
/// </summary>
75+
/// <param name="builder"></param>
76+
protected override void BuildRenderTree(RenderTreeBuilder builder)
77+
{
78+
if (OnErrorHandleAsync == null)
79+
{
80+
var ex = CurrentException ?? _exception;
81+
if (ex != null)
82+
{
83+
builder.AddContent(0, ExceptionContent(ex));
84+
}
85+
}
86+
builder.AddContent(1, ChildContent);
87+
}
88+
89+
private Exception? _exception = null;
90+
91+
private RenderFragment<Exception> ExceptionContent => ex => builder =>
92+
{
93+
if (ErrorContent != null)
94+
{
95+
builder.AddContent(0, ErrorContent(ex));
96+
}
97+
else
98+
{
99+
var index = 0;
100+
builder.OpenElement(index++, "div");
101+
builder.AddAttribute(index++, "class", "error-stack");
102+
builder.AddContent(index++, ex.FormatMarkupString(Configuration.GetEnvironmentInformation()));
103+
builder.CloseElement();
104+
}
105+
};
106+
107+
/// <summary>
108+
/// 渲染异常信息方法
109+
/// </summary>
110+
/// <param name="exception"></param>
111+
/// <param name="handler"></param>
112+
public async Task RenderException(Exception exception, IHandlerException? handler)
113+
{
114+
await OnErrorAsync(exception);
115+
116+
if (handler != null)
117+
{
118+
await handler.HandlerException(exception, ExceptionContent);
119+
}
120+
else
121+
{
122+
_exception = exception;
123+
StateHasChanged();
124+
}
125+
}
126+
}

src/BootstrapBlazor/Components/ErrorLogger/ErrorLogger.cs

Lines changed: 17 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

66
using Microsoft.AspNetCore.Components.Rendering;
7-
using Microsoft.AspNetCore.Components.Web;
87
using Microsoft.Extensions.Configuration;
98
using Microsoft.Extensions.Localization;
109
using Microsoft.Extensions.Logging;
@@ -14,25 +13,8 @@ namespace BootstrapBlazor.Components;
1413
/// <summary>
1514
/// ErrorLogger 全局异常组件
1615
/// </summary>
17-
public class ErrorLogger
18-
#if NET6_0_OR_GREATER
19-
: ErrorBoundaryBase, IErrorLogger
20-
#else
21-
: ComponentBase, IErrorLogger
22-
#endif
16+
public class ErrorLogger : ComponentBase, IErrorLogger
2317
{
24-
[Inject]
25-
[NotNull]
26-
private ILogger<ErrorLogger>? Logger { get; set; }
27-
28-
[Inject]
29-
[NotNull]
30-
private IConfiguration? Configuration { get; set; }
31-
32-
[Inject]
33-
[NotNull]
34-
private ToastService? ToastService { get; set; }
35-
3618
[Inject]
3719
[NotNull]
3820
private IStringLocalizer<ErrorLogger>? Localizer { get; set; }
@@ -62,28 +44,19 @@ public class ErrorLogger
6244
[Parameter]
6345
public Func<ILogger, Exception, Task>? OnErrorHandleAsync { get; set; }
6446

65-
#if NET6_0_OR_GREATER
66-
[Inject]
67-
[NotNull]
68-
private IErrorBoundaryLogger? ErrorBoundaryLogger { get; set; }
69-
#else
7047
/// <summary>
71-
///
48+
/// 获得/设置 子组件
7249
/// </summary>
7350
[Parameter]
7451
public RenderFragment? ChildContent { get; set; }
7552

7653
/// <summary>
77-
///
54+
/// 获得/设置 异常显示模板
7855
/// </summary>
7956
[Parameter]
80-
[NotNull]
8157
public RenderFragment<Exception>? ErrorContent { get; set; }
82-
#endif
83-
84-
private Exception? Exception { get; set; }
8558

86-
private bool ShowErrorDetails { get; set; }
59+
private BootstrapBlazorErrorBoundary _errorBoundary = default!;
8760

8861
/// <summary>
8962
/// <inheritdoc/>
@@ -93,77 +66,33 @@ protected override void OnInitialized()
9366
base.OnInitialized();
9467

9568
ToastTitle ??= Localizer[nameof(ToastTitle)];
96-
97-
ShowErrorDetails = Configuration.GetValue("DetailedErrors", false);
98-
99-
if (ShowErrorDetails)
100-
{
101-
ErrorContent ??= RenderException();
102-
}
103-
#if NET6_0_OR_GREATER
104-
MaximumErrorCount = 1;
105-
#endif
10669
}
10770

10871
/// <summary>
10972
/// <inheritdoc/>
11073
/// </summary>
111-
protected override void OnParametersSet()
112-
{
113-
base.OnParametersSet();
114-
Exception = null;
115-
116-
#if NET6_0_OR_GREATER
117-
Recover();
118-
#endif
119-
}
120-
121-
/// <summary>
122-
/// BuildRenderTree 方法
123-
/// </summary>
12474
/// <param name="builder"></param>
12575
protected override void BuildRenderTree(RenderTreeBuilder builder)
12676
{
12777
builder.OpenComponent<CascadingValue<IErrorLogger>>(0);
12878
builder.AddAttribute(1, nameof(CascadingValue<IErrorLogger>.Value), this);
12979
builder.AddAttribute(2, nameof(CascadingValue<IErrorLogger>.IsFixed), true);
130-
131-
var content = ChildContent;
132-
133-
if (EnableErrorLogger)
134-
{
135-
#if NET6_0_OR_GREATER
136-
var ex = Exception ?? CurrentException;
137-
#else
138-
var ex = Exception;
139-
#endif
140-
if (ex != null && ErrorContent != null)
141-
{
142-
if (_cache.Count > 0)
143-
{
144-
var component = _cache.Last();
145-
if (component is IHandlerException handler)
146-
{
147-
handler.HandlerException(ex, ErrorContent);
148-
}
149-
}
150-
else
151-
{
152-
content = ErrorContent.Invoke(ex);
153-
}
154-
}
155-
}
156-
builder.AddAttribute(3, nameof(CascadingValue<IErrorLogger>.ChildContent), content);
80+
builder.AddAttribute(3, nameof(CascadingValue<IErrorLogger>.ChildContent), RenderContent);
15781
builder.CloseComponent();
15882
}
15983

160-
private RenderFragment<Exception> RenderException() => ex => builder =>
84+
private RenderFragment? RenderContent => EnableErrorLogger ? RenderError : ChildContent;
85+
86+
private RenderFragment RenderError => builder =>
16187
{
162-
var index = 0;
163-
builder.OpenElement(index++, "div");
164-
builder.AddAttribute(index++, "class", "error-stack");
165-
builder.AddContent(index++, ex.FormatMarkupString(Configuration.GetEnvironmentInformation()));
166-
builder.CloseElement();
88+
builder.OpenComponent<BootstrapBlazorErrorBoundary>(0);
89+
builder.AddAttribute(1, nameof(BootstrapBlazorErrorBoundary.OnErrorHandleAsync), OnErrorHandleAsync);
90+
builder.AddAttribute(2, nameof(BootstrapBlazorErrorBoundary.ShowToast), ShowToast);
91+
builder.AddAttribute(3, nameof(BootstrapBlazorErrorBoundary.ToastTitle), ToastTitle);
92+
builder.AddAttribute(4, nameof(BootstrapBlazorErrorBoundary.ErrorContent), ErrorContent);
93+
builder.AddAttribute(5, nameof(BootstrapBlazorErrorBoundary.ChildContent), ChildContent);
94+
builder.AddComponentReferenceCapture(5, obj => _errorBoundary = (BootstrapBlazorErrorBoundary)obj);
95+
builder.CloseComponent();
16796
};
16897

16998
/// <summary>
@@ -172,47 +101,10 @@ private RenderFragment<Exception> RenderException() => ex => builder =>
172101
/// <param name="exception"></param>
173102
/// <returns></returns>
174103
public async Task HandlerExceptionAsync(Exception exception)
175-
{
176-
await OnErrorAsync(exception);
177-
178-
if (OnErrorHandleAsync is null && ShowErrorDetails)
179-
{
180-
Exception = exception;
181-
StateHasChanged();
182-
}
183-
}
184-
185-
/// <summary>
186-
/// OnErrorAsync 方法
187-
/// </summary>
188-
/// <param name="exception"></param>
189-
#if NET6_0_OR_GREATER
190-
protected override async Task OnErrorAsync(Exception exception)
191-
#else
192-
protected async Task OnErrorAsync(Exception exception)
193-
#endif
194104
{
195105
if (EnableErrorLogger)
196106
{
197-
// 由框架调用
198-
if (OnErrorHandleAsync != null)
199-
{
200-
await OnErrorHandleAsync(Logger, exception);
201-
}
202-
else
203-
{
204-
if (ShowToast)
205-
{
206-
await ToastService.Error(ToastTitle, exception.Message);
207-
}
208-
209-
#if NET6_0_OR_GREATER
210-
// 此处注意 内部 logLevel=Warning
211-
await ErrorBoundaryLogger.LogErrorAsync(exception);
212-
#else
213-
Logger.LogError(exception, "");
214-
#endif
215-
}
107+
await _errorBoundary.RenderException(exception, _cache.LastOrDefault());
216108
}
217109
}
218110

0 commit comments

Comments
 (0)