Skip to content

Commit a06fd97

Browse files
committed
Added ResultErrorHandler
1 parent 75b2db3 commit a06fd97

8 files changed

Lines changed: 159 additions & 12 deletions

File tree

ManagedCode.Communication.Tests/ManagedCode.Communication.Tests.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
</None>
1818
</ItemGroup>
1919
<ItemGroup>
20-
<PackageReference Include="FluentAssertions" Version="6.5.1"/>
21-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0"/>
22-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0"/>
23-
<PackageReference Include="xunit" Version="2.4.1"/>
20+
<PackageReference Include="FluentAssertions" Version="6.5.1" />
21+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
22+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
23+
<PackageReference Include="xunit" Version="2.4.1" />
2424
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
2525
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2626
<PrivateAssets>all</PrivateAssets>
@@ -36,7 +36,7 @@
3636
</ItemGroup>
3737

3838
<ItemGroup>
39-
<ProjectReference Include="..\ManagedCode.Communication\ManagedCode.Communication.csproj"/>
39+
<ProjectReference Include="..\ManagedCode.Communication\ManagedCode.Communication.csproj" />
4040
</ItemGroup>
4141

4242
</Project>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using FluentAssertions;
5+
using Microsoft.Extensions.Logging.Abstractions;
6+
using Xunit;
7+
8+
namespace ManagedCode.Communication.Tests;
9+
10+
public class ResultErrorHandlerTests
11+
{
12+
[Fact]
13+
public async Task ResultErrorHandler_Returns_Error_When_ThrowException()
14+
{
15+
var resultErrorHandler = new ResultErrorHandler(NullLogger<ResultErrorHandler>.Instance);
16+
var resultError = await resultErrorHandler.ExecuteAsync<TestResult, TestEnumCode>(ThrowException);
17+
18+
resultError.Error.Should().NotBeNull();
19+
}
20+
21+
public static Task<TestResult> ThrowException()
22+
{
23+
throw new Exception("Error");
24+
}
25+
}
26+
27+
public class TestResult : BaseResult<TestEnumCode>
28+
{
29+
public TestResult(bool isSuccess) : base(isSuccess)
30+
{
31+
}
32+
33+
public TestResult(Error<TestEnumCode> error) : base(error)
34+
{
35+
}
36+
37+
public TestResult(List<Error<TestEnumCode>> errors) : base(errors)
38+
{
39+
}
40+
}
41+
42+
public enum TestEnumCode
43+
{
44+
Test,
45+
}

ManagedCode.Communication.Tests/Tests.cs

Lines changed: 0 additions & 5 deletions
This file was deleted.

ManagedCode.Communication/BaseResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public abstract class BaseResult<TErrorCode> where TErrorCode : Enum
99
public bool IsSuccess { get; }
1010
public bool IsFail => !IsSuccess;
1111
public Error<TErrorCode>? Error => Errors?.FirstOrDefault();
12-
public List<Error<TErrorCode>>? Errors { get; set; }
12+
public List<Error<TErrorCode>>? Errors { get; }
1313

1414

1515
protected BaseResult(bool isSuccess)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace ManagedCode.Communication.Extensions;
5+
6+
internal static class LoggerExtensions
7+
{
8+
internal static void LogException(this ILogger logger, Exception exception)
9+
{
10+
logger.LogError(exception, exception.Message);
11+
}
12+
}

ManagedCode.Communication/ResultExtensions.cs renamed to ManagedCode.Communication/Extensions/ResultExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Threading.Tasks;
33

4-
namespace ManagedCode.Communication;
4+
namespace ManagedCode.Communication.Extensions;
55

66
public static class ResultExtensions
77
{

ManagedCode.Communication/ManagedCode.Communication.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
1819
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
1920
</ItemGroup>
2021

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
using System.Threading.Tasks;
4+
using ManagedCode.Communication.Extensions;
5+
using Microsoft.Extensions.Logging;
6+
7+
namespace ManagedCode.Communication;
8+
9+
public class ResultErrorHandler
10+
{
11+
private readonly ILogger<ResultErrorHandler>? _logger;
12+
13+
public ResultErrorHandler(ILogger<ResultErrorHandler>? logger)
14+
{
15+
_logger = logger;
16+
}
17+
18+
public async Task<Result> ExecuteAsync(Func<Task<Result>> func,
19+
[CallerMemberName] string memberName = "",
20+
[CallerFilePath] string sourceFilePath = "",
21+
[CallerLineNumber] int sourceLineNumber = 0)
22+
{
23+
try
24+
{
25+
var result = await func.Invoke();
26+
27+
if (result.IsFail)
28+
{
29+
_logger?.LogError($"{memberName} {result.Error} in {sourceFilePath}:line {sourceLineNumber} ");
30+
}
31+
32+
return result;
33+
}
34+
catch (Exception e)
35+
{
36+
_logger?.LogException(e);
37+
38+
return Result.Fail(Error<ErrorCode>.FromException(e));
39+
}
40+
}
41+
42+
public async Task<Result<TValue>> ExecuteAsync<TValue>(Func<Task<Result<TValue>>> func,
43+
[CallerMemberName] string memberName = "",
44+
[CallerFilePath] string sourceFilePath = "",
45+
[CallerLineNumber] int sourceLineNumber = 0)
46+
{
47+
try
48+
{
49+
var result = await func.Invoke();
50+
51+
if (result.IsFail)
52+
{
53+
_logger?.LogError($"{memberName} {result.Error?.ErrorCode} {result.Error?.Message} in {sourceFilePath}:line {sourceLineNumber} ");
54+
}
55+
56+
return result;
57+
}
58+
catch (Exception e)
59+
{
60+
_logger?.LogException(e);
61+
62+
return Result<TValue>.Fail(Error<ErrorCode>.FromException(e));
63+
}
64+
}
65+
66+
public async Task<TResult> ExecuteAsync<TResult, TErrorCode>(Func<Task<TResult>> func,
67+
[CallerMemberName] string memberName = "",
68+
[CallerFilePath] string sourceFilePath = "",
69+
[CallerLineNumber] int sourceLineNumber = 0) where TErrorCode : Enum where TResult : BaseResult<TErrorCode>
70+
{
71+
try
72+
{
73+
var result = await func.Invoke();
74+
75+
if (result.IsFail)
76+
{
77+
_logger?.LogError(
78+
$"{memberName} {result.Error?.ErrorCode?.ToString()} {result.Error?.Message} {result.Error} in {sourceFilePath}:line {sourceLineNumber} ");
79+
}
80+
81+
return result;
82+
}
83+
catch (Exception e)
84+
{
85+
_logger?.LogException(e);
86+
87+
var constructor = typeof(TResult).GetConstructor(new[] {typeof(Error<TErrorCode>)})!;
88+
89+
var obj = constructor.Invoke(new object[] {Error<TErrorCode>.FromException(e)}) as TResult;
90+
91+
return obj!;
92+
}
93+
}
94+
}

0 commit comments

Comments
 (0)