From 4aad2ad36b1f488f98e969bcc17ae2ca0f077d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Fri, 31 Dec 2021 11:13:56 +0100 Subject: [PATCH] feat: add support for logging nested results --- .../Extensions/ResultExtensions.cs | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/Core/NosSmooth.Core/Extensions/ResultExtensions.cs b/Core/NosSmooth.Core/Extensions/ResultExtensions.cs index 41c2dae..24ae4e5 100644 --- a/Core/NosSmooth.Core/Extensions/ResultExtensions.cs +++ b/Core/NosSmooth.Core/Extensions/ResultExtensions.cs @@ -5,6 +5,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.CodeDom.Compiler; +using System.IO; using System.Text; using Microsoft.Extensions.Logging; using Remora.Results; @@ -17,51 +19,68 @@ namespace NosSmooth.Core.Extensions; public static class ResultExtensions { /// - /// Logs the given result if it is errorful. + /// Logs the given result if it isn't successful. /// - /// The logger. + /// The logger to log with. /// The result to log. - /// Thrown if the result was unsuccessful. + /// Thrown if the result was successful. public static void LogResultError(this ILogger logger, IResult result) { if (result.IsSuccess) { - throw new InvalidOperationException("The result was successful, it has to be unsuccessful to log it."); + throw new InvalidOperationException("The result was successful, only unsuccessful results are supported."); } + using StringWriter stringWriter = new StringWriter(); + using IndentedTextWriter logTextWriter = new IndentedTextWriter(stringWriter, " "); + logTextWriter.Write("Encountered an error: "); + + LogResultError(logTextWriter, result); + logger.LogError(stringWriter.ToString()); + } + + private static void LogResultError(IndentedTextWriter logTextWriter, IResult result) + { switch (result.Error) { case AggregateError aggregateError: - logger.LogAggreggateError(aggregateError); + LogAggreggateError(logTextWriter, aggregateError); break; default: - logger.LogNestedError(result); + LogNestedError(logTextWriter, result); break; } } - private static void LogAggreggateError(this ILogger logger, AggregateError error) + private static void LogAggreggateError(IndentedTextWriter logTextWriter, AggregateError error) { foreach (var result in error.Errors) { - logger.LogResultError(result); + LogResultError(logTextWriter, result); } } - private static void LogNestedError(this ILogger logger, IResult? result) + private static void LogNestedError(IndentedTextWriter logTextWriter, IResult? result) { if ((result?.IsSuccess ?? true) || result.Error is null) { throw new InvalidOperationException("The result was successful, it has to be unsuccessful to log it."); } - var stringBuilder = new StringBuilder(result.Error.Message); - int index = 0; + logTextWriter.WriteLine(result.Error.Message); + IResultError? lastError = result.Error; while ((result = result?.Inner) is not null && result.Error is not null) { - stringBuilder.Append($"\n {index++}: {result.Error.Message}"); - } + // ReSharper disable once PossibleUnintendedReferenceComparison + if (lastError == result.Error) + { + continue; + } + lastError = result.Error; - logger.LogError(stringBuilder.ToString()); + logTextWriter.WriteLine("--- See the inner error ---"); + logTextWriter.Indent++; + logTextWriter.WriteLine(result.Error.Message); + } } } \ No newline at end of file -- 2.49.0