diff --git a/GFramework.Core.Tests/Logging/AsyncLogAppenderTests.cs b/GFramework.Core.Tests/Logging/AsyncLogAppenderTests.cs index cc22646..bd5576a 100644 --- a/GFramework.Core.Tests/Logging/AsyncLogAppenderTests.cs +++ b/GFramework.Core.Tests/Logging/AsyncLogAppenderTests.cs @@ -1,4 +1,3 @@ -using GFramework.Core.Abstractions.Logging; using GFramework.Core.Logging.Appenders; namespace GFramework.Core.Tests.Logging; @@ -197,6 +196,29 @@ public class AsyncLogAppenderTests Assert.That(asyncAppender.Flush(), Is.True); } + [Test] + public void Append_WhenInnerAppenderThrowsOperationCanceledException_ShouldNotReportError() + { + var reportedExceptions = new List(); + var innerAppender = new CancellationAppender(); + using var asyncAppender = new AsyncLogAppender( + innerAppender, + bufferSize: 1000, + processingErrorHandler: reportedExceptions.Add); + + Assert.DoesNotThrow(() => + { + for (int i = 0; i < 10; i++) + { + var entry = new LogEntry(DateTime.UtcNow, LogLevel.Info, "TestLogger", $"Message {i}", null, null); + asyncAppender.Append(entry); + } + }); + + Assert.That(asyncAppender.Flush(), Is.True); + Assert.That(reportedExceptions, Is.Empty); + } + // 辅助测试类 private class TestAppender : ILogAppender { @@ -257,4 +279,20 @@ public class AsyncLogAppenderTests { } } + + private class CancellationAppender : ILogAppender + { + public void Append(LogEntry entry) + { + throw new OperationCanceledException("Simulated cancellation"); + } + + public void Flush() + { + } + + public void Dispose() + { + } + } } \ No newline at end of file diff --git a/GFramework.Core/Logging/Appenders/AsyncLogAppender.cs b/GFramework.Core/Logging/Appenders/AsyncLogAppender.cs index 9d52b9b..556c7d3 100644 --- a/GFramework.Core/Logging/Appenders/AsyncLogAppender.cs +++ b/GFramework.Core/Logging/Appenders/AsyncLogAppender.cs @@ -1,4 +1,3 @@ -using System.Threading.Channels; using GFramework.Core.Abstractions.Logging; namespace GFramework.Core.Logging.Appenders; @@ -212,10 +211,16 @@ public sealed class AsyncLogAppender : ILogAppender /// /// 上报后台处理异常,同时隔离观察者自身抛出的错误,避免终止处理循环。 + /// 取消相关异常表示关闭流程中的预期控制流,不应被视为后台处理失败。 /// /// 后台处理中捕获到的异常。 private void ReportProcessingError(Exception exception) { + if (exception is OperationCanceledException) + { + return; + } + if (_processingErrorHandler is null) { return;