Skip to content

Commit 106cd98

Browse files
authored
Merge pull request #217 from zhenlineo/1.5-remove-AggregateException
Avoiding throw AggregateException
2 parents 1ef75d4 + 324f7f7 commit 106cd98

File tree

8 files changed

+42
-20
lines changed

8 files changed

+42
-20
lines changed

Neo4j.Driver/Neo4j.Driver.IntegrationTests/DirectDriver/SessionIT.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void ServiceUnavailableErrorWhenFailedToConn()
4242
exception = Record.Exception(() => session.Run("RETURN 1"));
4343
}
4444
exception.Should().BeOfType<ServiceUnavailableException>();
45-
exception.Message.Should().Be("Connection with the server breaks due to AggregateException: One or more errors occurred.");
45+
exception.Message.Should().Contain("Connection with the server breaks due to IOException");
4646
exception.GetBaseException().Should().BeOfType<SocketException>();
4747
exception.GetBaseException().Message.Should().Contain("No connection could be made because the target machine actively refused it");
4848
}

Neo4j.Driver/Neo4j.Driver.IntegrationTests/DirectDriver/TransactionIT.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ public void ShouldRetry()
4646
}));
4747
timer.Stop();
4848

49-
var error = e as AggregateException;
49+
e.Should().BeOfType<ServiceUnavailableException>();
50+
var error = e.InnerException as AggregateException;
5051
var innerErrors = error.Flatten().InnerExceptions;
5152
foreach (var innerError in innerErrors)
5253
{
5354
Output.WriteLine(innerError.Message);
55+
innerError.Should().BeOfType<SessionExpiredException>();
5456
}
5557
innerErrors.Count.Should().BeGreaterOrEqualTo(5);
5658
timer.Elapsed.TotalSeconds.Should().BeGreaterOrEqualTo(30);

Neo4j.Driver/Neo4j.Driver.IntegrationTests/Examples.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ public bool AddItem()
533533
);
534534
}
535535
}
536-
catch (AggregateException)
536+
catch (ServiceUnavailableException)
537537
{
538538
return false;
539539
}

Neo4j.Driver/Neo4j.Driver.IntegrationTests/ExamplesAsync.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ public async Task<bool> AddItemAsync()
614614
}
615615
);
616616
}
617-
catch (AggregateException)
617+
catch (ServiceUnavailableException)
618618
{
619619
return false;
620620
}

Neo4j.Driver/Neo4j.Driver.Tests/RetryLogicTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ private void Retry(int index, IRetryLogic retryLogic)
6262
}));
6363
timer.Stop();
6464

65-
var error = e as AggregateException;
65+
e.Should().BeOfType<ServiceUnavailableException>();
66+
var error = e.InnerException as AggregateException;
6667
var innerErrors = error.Flatten().InnerExceptions;
6768

6869
innerErrors.Count.Should().BeGreaterOrEqualTo(2);

Neo4j.Driver/Neo4j.Driver/Internal/Connector/SocketConnection.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,22 @@ internal SocketConnection(ISocketClient socketClient, IAuthToken authToken,
6666

6767
public void Init()
6868
{
69-
var connected = Task.Run(() => _client.StartAsync(_connectionTimeout)).Wait(_connectionTimeout);
70-
if (!connected)
69+
try
7170
{
72-
throw new IOException(
73-
$"Failed to connect to the server {Server.Address} within connection timeout {_connectionTimeout.TotalMilliseconds}ms");
71+
var connected = Task.Run(() => _client.StartAsync(_connectionTimeout)).Wait(_connectionTimeout);
72+
if (!connected)
73+
{
74+
throw new IOException(
75+
$"Failed to connect to the server {Server.Address} within connection timeout {_connectionTimeout.TotalMilliseconds}ms");
76+
}
77+
78+
Init(_authToken);
79+
}
80+
catch (AggregateException e)
81+
{
82+
// To remove the wrapper around the inner exception because of Task.Wait()
83+
throw e.InnerException;
7484
}
75-
76-
Init(_authToken);
7785
}
7886

7987
public async Task InitAsync()

Neo4j.Driver/Neo4j.Driver/Internal/Connector/TcpSocketClient.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
1717
using System;
18+
using System.Collections.Generic;
1819
using System.IO;
1920
using System.Net.Security;
2021
using System.Net.Sockets;
@@ -84,7 +85,7 @@ private async Task Connect(Uri uri, TimeSpan timeOut)
8485
using (CancellationTokenSource cancellationSource = new CancellationTokenSource(timeOut))
8586
{
8687
var addresses = await uri.ResolveAsync(_ipv6Enabled).ConfigureAwait(false);
87-
AggregateException innerErrors = null;
88+
var innerErrors = new List<Exception>();
8889
for (var i = 0; i < addresses.Length; i++)
8990
{
9091
try
@@ -101,13 +102,14 @@ private async Task Connect(Uri uri, TimeSpan timeOut)
101102
catch (Exception e)
102103
{
103104
var error = new IOException($"Failed to connect to server '{uri}' via IP address '{addresses[i]}': {e.Message}", e);
104-
innerErrors = innerErrors == null ? new AggregateException(error) : new AggregateException(innerErrors, error);
105+
innerErrors.Add(error);
105106

106107
if (i == addresses.Length - 1)
107108
{
108109
// if all failed
109110
throw new IOException(
110-
$"Failed to connect to server '{uri}' via IP addresses'{addresses.ToContentString()}' at port '{uri.Port}'.", innerErrors);
111+
$"Failed to connect to server '{uri}' via IP addresses'{addresses.ToContentString()}' at port '{uri.Port}'.",
112+
new AggregateException(innerErrors));
111113
}
112114
}
113115
}

Neo4j.Driver/Neo4j.Driver/Internal/RetryLogic.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,21 @@ public ExponentialBackoffRetryLogic(TimeSpan maxRetryTimeout, ILogger logger = n
6060

6161
public T Retry<T>(Func<T> runTxFunc)
6262
{
63-
AggregateException exception = null;
63+
var exceptions = new List<Exception>();
6464
var timer = new Stopwatch();
6565
timer.Start();
6666
var delayMs = _initialRetryDelayMs;
67+
var counter = 0;
6768
do
6869
{
70+
counter++;
6971
try
7072
{
7173
return runTxFunc();
7274
}
7375
catch (Exception e) when (e.IsRetriableError())
7476
{
75-
exception = exception == null ? new AggregateException(e) : new AggregateException(exception, e);
77+
exceptions.Add(e);
7678

7779
var delay = TimeSpan.FromMilliseconds(ComputeDelayWithJitter(delayMs));
7880
_logger?.Info("Transaction failed and will be retried in " + delay + "ms.", e);
@@ -82,24 +84,28 @@ public T Retry<T>(Func<T> runTxFunc)
8284
} while (timer.Elapsed.TotalMilliseconds < _maxRetryTimeMs);
8385

8486
timer.Stop();
85-
throw exception;
87+
throw new ServiceUnavailableException(
88+
$"Failed after retried for {counter} times in {_maxRetryTimeMs} ms. " +
89+
"Make sure that your database is online and retry again.", new AggregateException(exceptions));
8690
}
8791

8892
public async Task<T> RetryAsync<T>(Func<Task<T>> runTxAsyncFunc)
8993
{
90-
AggregateException exception = null;
94+
var exceptions = new List<Exception>();
9195
var timer = new Stopwatch();
9296
timer.Start();
9397
var delayMs = _initialRetryDelayMs;
98+
var counter = 0;
9499
do
95100
{
101+
counter++;
96102
try
97103
{
98104
return await runTxAsyncFunc().ConfigureAwait(false);
99105
}
100106
catch (Exception e) when (e.IsRetriableError())
101107
{
102-
exception = exception == null ? new AggregateException(e) : new AggregateException(exception, e);
108+
exceptions.Add(e);
103109

104110
var delay = TimeSpan.FromMilliseconds(ComputeDelayWithJitter(delayMs));
105111
_logger?.Info("Transaction failed and will be retried in " + delay + "ms.", e);
@@ -109,7 +115,10 @@ public async Task<T> RetryAsync<T>(Func<Task<T>> runTxAsyncFunc)
109115
} while (timer.Elapsed.TotalMilliseconds < _maxRetryTimeMs);
110116

111117
timer.Stop();
112-
throw exception;
118+
throw new ServiceUnavailableException(
119+
$"Failed after retried for {counter} times in {_maxRetryTimeMs} ms. " +
120+
"Make sure that your database is online and retry again.", new AggregateException(exceptions));
121+
113122
}
114123

115124
private double ComputeDelayWithJitter(double delayMs)

0 commit comments

Comments
 (0)