Skip to content

Commit 4edeba2

Browse files
Add ThrowIfFail method with stack trace preserved
1 parent b9a59ae commit 4edeba2

8 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"profiles": {
3+
"ManagedCode.Communication.Extensions": {
4+
"commandName": "Project",
5+
"launchBrowser": true,
6+
"environmentVariables": {
7+
"ASPNETCORE_ENVIRONMENT": "Development"
8+
},
9+
"applicationUrl": "https://localhost:7106;http://localhost:7107"
10+
}
11+
}
12+
}

ManagedCode.Communication.Tests/Collections/CollectionResultSucceedTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public void Succeed()
1717
ok.IsFailed.Should().BeFalse();
1818
ok.GetError().Should().BeNull();
1919
ok.ThrowIfFail();
20+
ok.ThrowIfFailWithStackPreserved();
2021
Assert.True(ok == true);
2122
Assert.True(ok);
2223
ok.AsTask().Result.IsSuccess.Should().BeTrue();
@@ -38,6 +39,7 @@ public void SucceedPaged()
3839
ok.IsFailed.Should().BeFalse();
3940
ok.GetError().Should().BeNull();
4041
ok.ThrowIfFail();
42+
ok.ThrowIfFailWithStackPreserved();
4143
Assert.True(ok == true);
4244
Assert.True(ok);
4345
ok.AsTask().Result.IsSuccess.Should().BeTrue();
@@ -59,6 +61,7 @@ public void FailWithoutError()
5961
fail.IsFailed.Should().BeTrue();
6062
fail.GetError().Should().BeNull();
6163
Assert.Throws<Exception>(() => fail.ThrowIfFail());
64+
Assert.Throws<Exception>(() => fail.ThrowIfFailWithStackPreserved());
6265
Assert.True(fail == false);
6366
Assert.False(fail);
6467
fail.AsTask().Result.IsSuccess.Should().BeFalse();
@@ -74,6 +77,7 @@ public void FailWithError()
7477
fail.GetError().Should().NotBeNull();
7578
fail.GetError()?.Message.Should().Be("Test Error");
7679
Assert.Throws<Exception>(() => fail.ThrowIfFail());
80+
Assert.Throws<Exception>(() => fail.ThrowIfFailWithStackPreserved());
7781
Assert.True(fail == false);
7882
Assert.False(fail);
7983
fail.AsTask().Result.IsSuccess.Should().BeFalse();
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"profiles": {
3+
"ManagedCode.Communication.Tests": {
4+
"commandName": "Project",
5+
"launchBrowser": true,
6+
"environmentVariables": {
7+
"ASPNETCORE_ENVIRONMENT": "Development"
8+
},
9+
"applicationUrl": "https://localhost:7104;http://localhost:7105"
10+
}
11+
}
12+
}

ManagedCode.Communication/CollectionResultT/CollectionResult.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Diagnostics;
44
using System.Diagnostics.CodeAnalysis;
55
using System.Linq;
6+
using System.Runtime.ExceptionServices;
67
using System.Text.Json.Serialization;
78
using ManagedCode.Communication.Extensions;
89

@@ -61,6 +62,26 @@ public void ThrowIfFail()
6162
throw new AggregateException(exceptions);
6263
}
6364

65+
public void ThrowIfFailWithStackPreserved()
66+
{
67+
if (Errors?.Any() is not true)
68+
{
69+
if (IsFailed)
70+
throw new Exception(nameof(IsFailed));
71+
72+
return;
73+
}
74+
75+
var exceptions = Errors.Select(s => s.ExceptionInfo() ?? ExceptionDispatchInfo.Capture(new Exception(string.Join(';', s.ErrorCode, s.Message))));
76+
77+
if (Errors.Length == 1)
78+
{
79+
exceptions.First().Throw();
80+
}
81+
82+
throw new AggregateException(exceptions.Select(e => e.SourceException));
83+
}
84+
6485
[MemberNotNullWhen(true, nameof(Collection))]
6586
public bool IsSuccess { get; set; }
6687

ManagedCode.Communication/Error.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Runtime.ExceptionServices;
23
using System.Text.Json.Serialization;
34

45
namespace ManagedCode.Communication;
@@ -37,6 +38,16 @@ internal Error(Exception? exception, string message, string? errorCode = default
3738
return ExceptionObject as Exception;
3839
}
3940

41+
public ExceptionDispatchInfo? ExceptionInfo()
42+
{
43+
if (ExceptionObject is Exception exception)
44+
{
45+
return ExceptionDispatchInfo.Capture(exception);
46+
}
47+
48+
return null;
49+
}
50+
4051
public T? Exception<T>() where T : class
4152
{
4253
if (ExceptionObject is T exception)

ManagedCode.Communication/IResultError.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public interface IResultError
2424
/// </summary>
2525
void ThrowIfFail();
2626

27+
/// <summary>
28+
/// Throws an exception with stack trace preserved if the result indicates a failure.
29+
/// </summary>
30+
void ThrowIfFailWithStackPreserved();
31+
2732
/// <summary>
2833
/// Gets the error code as a specific enumeration type.
2934
/// </summary>

ManagedCode.Communication/Result/Result.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Linq;
5+
using System.Runtime.ExceptionServices;
56
using System.Text.Json.Serialization;
67
using ManagedCode.Communication.Extensions;
78

@@ -84,6 +85,29 @@ public void ThrowIfFail()
8485
throw new AggregateException(exceptions);
8586
}
8687

88+
/// <summary>
89+
/// Throws an exception with stack trace preserved if the result indicates a failure.
90+
/// </summary>
91+
public void ThrowIfFailWithStackPreserved()
92+
{
93+
if (Errors?.Any() is not true)
94+
{
95+
if (IsFailed)
96+
throw new Exception(nameof(IsFailed));
97+
98+
return;
99+
}
100+
101+
var exceptions = Errors.Select(s => s.ExceptionInfo() ?? ExceptionDispatchInfo.Capture(new Exception(string.Join(';', s.ErrorCode, s.Message))));
102+
103+
if (Errors.Length == 1)
104+
{
105+
exceptions.First().Throw();
106+
}
107+
108+
throw new AggregateException(exceptions.Select(e => e.SourceException));
109+
}
110+
87111
/// <summary>
88112
/// Gets the error code as a specific enumeration type.
89113
/// </summary>

ManagedCode.Communication/ResultT/Result.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Diagnostics;
44
using System.Diagnostics.CodeAnalysis;
55
using System.Linq;
6+
using System.Runtime.ExceptionServices;
67
using System.Text.Json.Serialization;
78
using ManagedCode.Communication.Extensions;
89

@@ -72,6 +73,29 @@ public void ThrowIfFail()
7273
throw new AggregateException(exceptions);
7374
}
7475

76+
/// <summary>
77+
/// Throws an exception with stack trace preserved if the result indicates a failure.
78+
/// </summary>
79+
public void ThrowIfFailWithStackPreserved()
80+
{
81+
if (Errors?.Any() is not true)
82+
{
83+
if (IsFailed)
84+
throw new Exception(nameof(IsFailed));
85+
86+
return;
87+
}
88+
89+
var exceptions = Errors.Select(s => s.ExceptionInfo() ?? ExceptionDispatchInfo.Capture(new Exception(string.Join(';', s.ErrorCode, s.Message))));
90+
91+
if (Errors.Length == 1)
92+
{
93+
exceptions.First().Throw();
94+
}
95+
96+
throw new AggregateException(exceptions.Select(e => e.SourceException));
97+
}
98+
7599
/// <summary>
76100
/// Gets a value indicating whether the result is a success.
77101
/// </summary>

0 commit comments

Comments
 (0)