Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Reflection;

Expand All @@ -31,6 +32,10 @@ class BootstrapBlazorErrorBoundary : ErrorBoundaryBase
[NotNull]
private NavigationManager? NavigationManager { get; set; }

[Inject]
[NotNull]
private IHostEnvironment? HostEnvironment { get; set; }

/// <summary>
/// 获得/设置 自定义错误处理回调方法
/// </summary>
Expand All @@ -54,13 +59,10 @@ class BootstrapBlazorErrorBoundary : ErrorBoundaryBase
/// <inheritdoc/>
/// </summary>
/// <param name="exception"></param>
protected override async Task OnErrorAsync(Exception exception)
protected override Task OnErrorAsync(Exception exception)
{
if (ShowToast)
{
await ToastService.Error(ToastTitle, exception.Message);
}
Logger.LogError(exception, "{BootstrapBlazorErrorBoundary} {OnErrorAsync} log this error occurred at {Page}", nameof(BootstrapBlazorErrorBoundary), nameof(OnErrorAsync), NavigationManager.Uri);
return Task.CompletedTask;
}

/// <summary>
Expand All @@ -69,13 +71,13 @@ protected override async Task OnErrorAsync(Exception exception)
/// <param name="builder"></param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
// 页面生命周期内异常直接调用这里
var ex = CurrentException ?? _exception;
if (ex != null)
{
// 处理自定义异常逻辑
if (OnErrorHandleAsync != null)
{
// 页面生命周期内异常直接调用这里
_ = OnErrorHandleAsync(Logger, ex);
return;
}
Expand Down Expand Up @@ -132,7 +134,7 @@ private MarkupString GetErrorContentMarkupString(Exception ex)
}

/// <summary>
/// 渲染异常信息方法
/// BootstrapBlazor 组件导致异常渲染方法
/// </summary>
/// <param name="exception"></param>
/// <param name="handler"></param>
Expand All @@ -145,14 +147,35 @@ public async Task RenderException(Exception exception, IHandlerException? handle
return;
}

// 记录日志
await OnErrorAsync(exception);

if (handler != null)
{
await handler.HandlerException(exception, ExceptionContent);
if (HostEnvironment.IsDevelopment())
{
// IHandlerException 处理异常逻辑
await handler.HandlerException(exception, ExceptionContent);
}
else
{
// 非开发模式下弹窗提示错误信息
await ToastService.Error(ToastTitle, exception.Message);
}
return;
}

await OnErrorAsync(exception);
// 显示异常信息
await ShowErrorToast(exception);
_exception = exception;
StateHasChanged();
}

private async Task ShowErrorToast(Exception exception)
{
if (ShowToast)
{
await ToastService.Error(ToastTitle, exception.Message);
}
}
}
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Layout/Layout.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ private Task OnErrorLoggerInitialized(ErrorLogger logger)
private RenderFragment? _errorContent;

/// <summary>
/// HandlerException 错误处理方法
/// <inheritdoc/>
/// </summary>
/// <param name="ex"></param>
/// <param name="errorContent"></param>
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Modal/ModalDialog.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ private RenderFragment RenderBodyTemplate() => builder =>
protected RenderFragment? _errorContent;

/// <summary>
/// HandlerException 错误处理方法
/// <inheritdoc/>
/// </summary>
/// <param name="ex"></param>
/// <param name="errorContent"></param>
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Tab/TabItemContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void Render()
}

/// <summary>
/// HandlerException 错误处理方法
/// <inheritdoc/>
/// </summary>
/// <param name="ex"></param>
/// <param name="errorContent"></param>
Expand Down
4 changes: 4 additions & 0 deletions src/BootstrapBlazor/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="$(NET6Version)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(NET8Version)" />
</ItemGroup>

Expand All @@ -44,6 +45,7 @@
<PackageReference Include="Microsoft.Extensions.Localization" Version="$(NET7Version)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(NET8Version)" />
</ItemGroup>

Expand All @@ -53,6 +55,7 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(NET8Version)" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="$(NET8Version)" />
</ItemGroup>

Expand All @@ -62,6 +65,7 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(NET9Version)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(NET9Version)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="$(NET9Version)" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(NET9Version)" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="$(NET9Version)" />
</ItemGroup>

Expand Down
17 changes: 6 additions & 11 deletions test/UnitTest/Components/BootstrapBlazorRootTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,19 @@

//using HarmonyLib;

using Bunit.TestDoubles;

namespace UnitTest.Components;

public class BootstrapBlazorRootTest : TestBase
{
[Fact]
public void Render_Ok()
{
var context = new TestContext();
context.JSInterop.Mode = JSRuntimeMode.Loose;

var sc = context.Services;
sc.AddBootstrapBlazor();
sc.ConfigureJsonLocalizationOptions(op =>
{
op.IgnoreLocalizerMissing = false;
});
sc.AddScoped<IRootComponentGenerator, MockGenerator>();
var cut = context.RenderComponent<BootstrapBlazorRoot>();
Context.Services.AddBootstrapBlazor();
Context.Services.AddScoped<IRootComponentGenerator, MockGenerator>();
Context.Services.GetRequiredService<ICacheManager>();
var cut = Context.RenderComponent<BootstrapBlazorRoot>();
cut.Contains("<div class=\"auto-generator\"></div>");
}

Expand Down
39 changes: 38 additions & 1 deletion test/UnitTest/Components/ErrorLoggerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;

namespace UnitTest.Components;

Expand Down Expand Up @@ -161,7 +163,7 @@ public void ErrorContent_Ok()
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.Add(a => a.EnableErrorLogger, true);
pb.Add(a => a.ShowToast, false);
pb.Add(a => a.ShowToast, true);
pb.AddChildContent<Button>(pb =>
{
pb.Add(b => b.OnClick, () =>
Expand Down Expand Up @@ -217,6 +219,30 @@ public async Task TabItem_Error()
((IDisposable)content).Dispose();
}

[Fact]
public async Task TabItem_Production_Error()
{
var context = new TestContext();
context.JSInterop.Mode = JSRuntimeMode.Loose;
context.Services.AddSingleton<IHostEnvironment, MockProductionEnironment>();
context.Services.AddBootstrapBlazor();
context.Services.GetRequiredService<ICacheManager>();

var cut = context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Tab>(pb =>
{
pb.AddChildContent<TabItem>(pb =>
{
pb.Add(a => a.Text, "Text1");
pb.Add(a => a.ChildContent, builder => builder.AddContent(0, RenderButton()));
});
});
});
var button = cut.Find("button");
await cut.InvokeAsync(() => button.Click());
}

private RenderFragment RenderButton() => builder =>
{
builder.OpenComponent<Button>(0);
Expand All @@ -227,4 +253,15 @@ private RenderFragment RenderButton() => builder =>
}));
builder.CloseComponent();
};

class MockProductionEnironment : IHostEnvironment
{
public string EnvironmentName { get; set; } = "Production";

public string ApplicationName { get; set; } = "Test";

public string ContentRootPath { get; set; } = "UniTest";

public IFileProvider ContentRootFileProvider { get; set; } = null!;
}
}
2 changes: 2 additions & 0 deletions test/UnitTest/Core/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ public TestBase()
{
Context = new TestContext();
Context.JSInterop.Mode = JSRuntimeMode.Loose;

Context.Services.AddMockEnvironment();
}
}
19 changes: 19 additions & 0 deletions test/UnitTest/Extensions/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;

namespace Microsoft.Extensions.DependencyInjection;

Expand All @@ -24,4 +26,21 @@ public static IServiceCollection AddConfiguration(this IServiceCollection servic
services.AddSingleton<IConfiguration>(config);
return services;
}

public static IServiceCollection AddMockEnvironment(this IServiceCollection services)
{
services.AddSingleton<IHostEnvironment, MockEnvironment>();
return services;
}

class MockEnvironment : IHostEnvironment
{
public string EnvironmentName { get; set; } = "Development";

public string ApplicationName { get; set; } = "Test";

public string ContentRootPath { get; set; } = "UnitTest";

public IFileProvider ContentRootFileProvider { get; set; } = null!;
}
}
34 changes: 9 additions & 25 deletions test/UnitTest/Services/MaskServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@ namespace UnitTest.Services;
/// <summary>
/// MaskService 单元测试
/// </summary>
public class MaskServiceTest : TestBase
public class MaskServiceTest : BootstrapBlazorTestBase
{
[Fact]
public async Task Mask_Ok()
{
var context = new TestContext();
context.JSInterop.Mode = JSRuntimeMode.Loose;
context.Services.AddBootstrapBlazor();

var maskService = context.Services.GetRequiredService<MaskService>();
var cut = context.RenderComponent<BootstrapBlazorRoot>(pb =>
var maskService = Context.Services.GetRequiredService<MaskService>();
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Button>(pb =>
{
Expand Down Expand Up @@ -49,12 +45,8 @@ await maskService.Show(new MaskOption()
[Fact]
public async Task Container_Ok()
{
var context = new TestContext();
context.JSInterop.Mode = JSRuntimeMode.Loose;
context.Services.AddBootstrapBlazor();

var maskService = context.Services.GetRequiredService<MaskService>();
var cut = context.RenderComponent<BootstrapBlazorRoot>(pb =>
var maskService = Context.Services.GetRequiredService<MaskService>();
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Button>(pb =>
{
Expand Down Expand Up @@ -87,12 +79,8 @@ await maskService.Show(new MaskOption()
[Fact]
public async Task Show_Component()
{
var context = new TestContext();
context.JSInterop.Mode = JSRuntimeMode.Loose;
context.Services.AddBootstrapBlazor();

var maskService = context.Services.GetRequiredService<MaskService>();
var cut = context.RenderComponent<BootstrapBlazorRoot>(pb =>
var maskService = Context.Services.GetRequiredService<MaskService>();
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Button>(pb =>
{
Expand All @@ -109,12 +97,8 @@ public async Task Show_Component()
[Fact]
public async Task Show_Type()
{
var context = new TestContext();
context.JSInterop.Mode = JSRuntimeMode.Loose;
context.Services.AddBootstrapBlazor();

var maskService = context.Services.GetRequiredService<MaskService>();
var cut = context.RenderComponent<BootstrapBlazorRoot>(pb =>
var maskService = Context.Services.GetRequiredService<MaskService>();
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Button>(pb =>
{
Expand Down