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 @@ -47,7 +47,8 @@
/// 扫描指定程序集集合(缺省 = 当前 AppDomain 全部已加载程序集;同 Id 多实现 fail-fast)。
/// </summary>
/// <param name="assemblies">程序集集合(null = 全部已加载)。</param>
/// <returns>发现的能力模块(按程序集名 + 类型名稳定排序;同 Id 多实现抛 <see cref="InvalidOperationException"/>)。</returns>
/// <returns>发现的能力模块(按程序集名 + 类型名稳定排序;同 Id 多实现抛 <see cref="InvalidOperationException"/>;
/// 程序集类型无法完整加载抛 <see cref="CapabilityAssemblyException"/>)。</returns>
public static IReadOnlyList<ICapabilityModule> DiscoverModules(IEnumerable<Assembly> assemblies = null)
{
var targetAssemblies = assemblies ?? AppDomain.CurrentDomain.GetAssemblies();
Expand Down Expand Up @@ -144,7 +145,19 @@
catch (ReflectionTypeLoadException exception)
{
// 命中命名约定的能力包类型无法完整加载(如依赖缺失)= 部署残缺——带定位信息 fail-fast,不再静默跳过。
throw new InvalidOperationException(string.Format(LocalizationService.GetString(Localization.Keys.Capability.Hosting.ModuleTypeScanFailed), assembly.GetName().Name, exception.LoaderExceptions == null ? 0 : exception.LoaderExceptions.Length));
// 抛 CapabilityAssemblyException:组合入口统一经 RenderFailures 逐条打 Error,首条为程序集定位,其后逐条保留底层加载原因。
var loaderExceptions = exception.LoaderExceptions ?? Array.Empty<Exception>();
var problems = new List<string>(loaderExceptions.Length + 1);
problems.Add(string.Format(LocalizationService.GetString(Localization.Keys.Capability.Hosting.ModuleTypeScanFailed), assembly.GetName().Name, loaderExceptions.Length));
foreach (var loaderException in loaderExceptions)

Check warning on line 152 in Capability/GameFrameX.Capability.Hosting.Core/CapabilityAssembly.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Loops should be simplified using the "Where" LINQ method

See more on https://sonarcloud.io/project/issues?id=GameFrameX.Server.Source&issues=AaFyYAjJdA8JAur1Rkmp&open=AaFyYAjJdA8JAur1Rkmp&pullRequest=642
{
if (loaderException != null)
{
problems.Add(loaderException.Message);
}
}

throw new CapabilityAssemblyException(problems, exception);
}

foreach (var type in types)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ public CapabilityAssemblyException(IReadOnlyList<string> problems)
Problems = problems;
}

/// <summary>
/// 初始化 <see cref="CapabilityAssemblyException"/>(保留触发问题的原始异常,供诊断堆栈与底层异常对象)。
/// </summary>
/// <param name="problems">全部问题条目(已本地化;至少一条)。</param>
/// <param name="innerException">触发问题的原始异常。</param>
public CapabilityAssemblyException(IReadOnlyList<string> problems, Exception innerException)
: base(BuildMessage(problems), innerException)
{
Problems = problems;
}

/// <summary>
/// 获取全部问题条目(已本地化)。
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public void LoadDeploymentAssemblies_CorruptArtifact_FailsFastWithProblems()
}

/// <summary>
/// 类型无法完整加载的能力包(依赖缺失)不再静默跳过:带程序集名定位信息 fail-fast。
/// 类型无法完整加载的能力包(依赖缺失)不再静默跳过:抛 <see cref="CapabilityAssemblyException"/>,
/// 首条问题带程序集名定位,其后逐条保留底层类型加载原因(组合入口据此经 RenderFailures 一次报全)。
/// </summary>
[Fact]
public void DiscoverModules_UnloadableTypes_FailsFastWithAssemblyName()
Expand All @@ -100,8 +101,11 @@ public void DiscoverModules_UnloadableTypes_FailsFastWithAssemblyName()
{
var assembly = Assembly.LoadFrom(path);

var exception = Assert.Throws<InvalidOperationException>(() => CapabilityAssembly.DiscoverModules(new[] { assembly, }));
Assert.Contains("CapabilityDeploymentScanProbe.Broken", exception.Message);
var exception = Assert.Throws<CapabilityAssemblyException>(() => CapabilityAssembly.DiscoverModules(new[] { assembly, }));
Assert.Contains("CapabilityDeploymentScanProbe.Broken", exception.Problems[0]);
Assert.True(exception.Problems.Count > 1);
Assert.Contains(exception.Problems.Skip(1), problem => problem.Contains("CapabilityDeploymentScanProbe.Missing"));
Assert.IsType<ReflectionTypeLoadException>(exception.InnerException);
}
finally
{
Expand Down
Loading