From 5046c9752b9651103ee16ae9c7bbef2ae3d7f609 Mon Sep 17 00:00:00 2001
From: GeWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Sat, 18 Apr 2026 21:09:08 +0800
Subject: [PATCH] =?UTF-8?q?fix(review-followup):=20=E4=BF=AE=E5=A4=8D?=
=?UTF-8?q?=E6=97=A5=E5=BF=97=E9=85=8D=E7=BD=AE=E7=A9=BA=E9=A1=B9=E6=A0=A1?=
=?UTF-8?q?=E9=AA=8C=E4=B8=8E=E6=96=87=E6=A1=A3=E7=A4=BA=E4=BE=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 修复 ConfigurableLoggerFactory 对 null Appender 配置项的显式校验与 XML 契约
- 补充日志工厂针对 appenders 空项输入的回归测试
- 更新 Godot setting 文档中的 async 示例签名以匹配 ApplyAsync 用法
- 修正 AbstractArchitecture 中 ObserveDestroyCoreAsync 方法里调用await DestroyAsync() 未配置ConfigureAwait(false)的问题
---
.../Logging/ConfigurableLoggerFactoryTests.cs | 18 ++++++++++++++++++
.../Logging/ConfigurableLoggerFactory.cs | 10 +++++++++-
.../Architectures/AbstractArchitecture.cs | 4 +---
docs/zh-CN/godot/setting.md | 4 ++--
4 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/GFramework.Core.Tests/Logging/ConfigurableLoggerFactoryTests.cs b/GFramework.Core.Tests/Logging/ConfigurableLoggerFactoryTests.cs
index 074c9a02..b20dd184 100644
--- a/GFramework.Core.Tests/Logging/ConfigurableLoggerFactoryTests.cs
+++ b/GFramework.Core.Tests/Logging/ConfigurableLoggerFactoryTests.cs
@@ -36,6 +36,24 @@ public sealed class ConfigurableLoggerFactoryTests
});
}
+ ///
+ /// 验证当配置输入把 appenders 集合中的某个元素反序列化为 时,工厂会抛出可诊断异常。
+ ///
+ [Test]
+ public void CreateFactory_ShouldThrowInvalidOperationException_WhenAppenderEntryIsNull()
+ {
+ var config = LoggingConfigurationLoader.LoadFromJsonString(
+ """
+ {
+ "appenders": [ null ]
+ }
+ """);
+
+ var exception = Assert.Throws(() => LoggingConfigurationLoader.CreateFactory(config));
+
+ Assert.That(exception!.Message, Is.EqualTo("Appender configuration cannot be null."));
+ }
+
///
/// 验证在未命中命名空间覆盖时,调用方传入的默认最小级别会作为最终 logger 级别的下限参与计算。
///
diff --git a/GFramework.Core/Logging/ConfigurableLoggerFactory.cs b/GFramework.Core/Logging/ConfigurableLoggerFactory.cs
index 5e4b497e..4d1fd064 100644
--- a/GFramework.Core/Logging/ConfigurableLoggerFactory.cs
+++ b/GFramework.Core/Logging/ConfigurableLoggerFactory.cs
@@ -16,6 +16,8 @@ internal sealed class ConfigurableLoggerFactory : ILoggerFactory, IDisposable
/// 初始化一个基于日志配置创建输出管线的工厂实例。
///
/// 日志配置。
+ /// 为 。
+ /// 配置中的某个 Appender 项为 。
public ConfigurableLoggerFactory(LoggingConfiguration config)
{
_config = config ?? throw new ArgumentNullException(nameof(config));
@@ -23,7 +25,13 @@ internal sealed class ConfigurableLoggerFactory : ILoggerFactory, IDisposable
// 反序列化输入可能显式把集合写成 null,这里统一归一化为可安全枚举的空集合。
_config.Appenders ??= [];
_config.LoggerLevels ??= new Dictionary(StringComparer.Ordinal);
- _appenders = _config.Appenders.Select(LoggingConfigurationLoader.CreateAppender).ToArray();
+
+ // 外部配置可能把集合项反序列化为 null,这里先给出可诊断异常,避免后续工厂链路出现不清晰的空引用失败。
+ _appenders = _config.Appenders
+ .Select(static appenderConfig => appenderConfig ??
+ throw new InvalidOperationException("Appender configuration cannot be null."))
+ .Select(LoggingConfigurationLoader.CreateAppender)
+ .ToArray();
}
///
diff --git a/GFramework.Godot/Architectures/AbstractArchitecture.cs b/GFramework.Godot/Architectures/AbstractArchitecture.cs
index 668c84ce..1beb8609 100644
--- a/GFramework.Godot/Architectures/AbstractArchitecture.cs
+++ b/GFramework.Godot/Architectures/AbstractArchitecture.cs
@@ -2,8 +2,6 @@
using GFramework.Core.Abstractions.Environment;
using GFramework.Core.Architectures;
using GFramework.Core.Constants;
-using GFramework.Godot.Extensions;
-using Godot;
namespace GFramework.Godot.Architectures;
@@ -165,7 +163,7 @@ public abstract class AbstractArchitecture(
{
try
{
- await DestroyAsync();
+ await DestroyAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
diff --git a/docs/zh-CN/godot/setting.md b/docs/zh-CN/godot/setting.md
index f1c75ae5..8187f303 100644
--- a/docs/zh-CN/godot/setting.md
+++ b/docs/zh-CN/godot/setting.md
@@ -378,7 +378,7 @@ public class AudioManager : Node
);
}
- private void SetMasterVolume(float linearVolume)
+ private async void SetMasterVolume(float linearVolume)
{
var settings = new AudioSettings { MasterVolume = linearVolume };
var audioSettings = new GodotAudioSettings(settings, new AudioBusMap());
@@ -419,7 +419,7 @@ public class CustomAudioManager : Node
);
}
- private void SetMasterVolume(float linearVolume)
+ private async void SetMasterVolume(float linearVolume)
{
var audioSettingsData = new AudioSettings { MasterVolume = linearVolume };
var audioSettings = new GodotAudioSettings(audioSettingsData, _customBusMap);