Skip to content

Commit bb25150

Browse files
authored
Merge pull request #15 from Makaopior/fix/async-timeout-exception
Throw TimeoutException instead of OperationCanceledException when RawQueryAsync method times out
2 parents 2c29f82 + 97de5d3 commit bb25150

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

RELEASE-NOTES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
v.6.1.0
2+
- Throw TimeoutException instead of OperationCanceledException when RawQueryAsync method times out
3+
14
v.6.0.0
25
- [BREAKING CHANGE] The Default timeout for communication with servers was changed to 2 seconds, and the default retry count was changed to 3 times (Issue #10 by Makaopior)
36
- Improved resolving an organization name from a raw response text from a WHOIS server

WhoisClient.NET.Test/IrregularCaseTests.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Net.Sockets;
1+
using System;
2+
using System.Net.Sockets;
23
using System.Text;
34
using NUnit.Framework;
45
using Whois.NET;
@@ -110,6 +111,49 @@ public async Task Default_Timeout_Async_Test()
110111
cts.Token.IsCancellationRequested.IsFalse();
111112
}
112113

114+
[Test]
115+
public void Default_Timeout_WithExceptionRethrow_Test()
116+
{
117+
// Given: a server that never shuts down
118+
using var server = new MockServer((client, token) => Task.Delay(int.MaxValue, token));
119+
120+
// When: a query is made to the server
121+
using var cts = new CancellationTokenSource(millisecondsDelay: 5000);
122+
var action = () => Task.Run(() =>
123+
WhoisClient.RawQuery("example.jp", options: new()
124+
{
125+
Server = "localhost",
126+
Port = server.Port,
127+
RethrowExceptions = true
128+
}), cts.Token);
129+
130+
// Then: IOException should be thrown
131+
Assert.ThrowsAsync<IOException>(new AsyncTestDelegate(action));
132+
133+
cts.Token.IsCancellationRequested.IsFalse();
134+
}
135+
136+
[Test]
137+
public void Default_Timeout_WithExceptionRethrow_Async_Test()
138+
{
139+
// Given: a server that never shuts down
140+
using var server = new MockServer((client, token) => Task.Delay(int.MaxValue, token));
141+
142+
// When: a query is made to the server
143+
using var cts = new CancellationTokenSource(millisecondsDelay: 5000);
144+
var action = () => WhoisClient.RawQueryAsync("example.jp", options: new()
145+
{
146+
Server = "localhost",
147+
Port = server.Port,
148+
RethrowExceptions = true
149+
}, cts.Token);
150+
151+
// Then: TimeoutException should be thrown
152+
Assert.ThrowsAsync<TimeoutException>(new AsyncTestDelegate(action));
153+
154+
cts.Token.IsCancellationRequested.IsFalse();
155+
}
156+
113157
[Test]
114158
public async Task Default_RetryCount_Test()
115159
{

WhoisClient.NET/WhoisClient.NET.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<AssemblyName>WhoisClient</AssemblyName>
1010
<Product>WhoisClient.NET</Product>
1111
<Authors>J.Sakamoto, Keith J. Jones, Martijn Storck, Makaopior</Authors>
12-
<Version>6.0.0</Version>
12+
<Version>6.1.0</Version>
1313
<Copyright>Copyright 2012-2025 J.Sakamoto; 2016 Keith J. Jones; 2023 Martijn Storck; 2025 Makaopior; Ms-PL License.</Copyright>
1414
<PackageLicenseExpression>MS-PL</PackageLicenseExpression>
1515
<PackageProjectUrl>https://github.com/jsakamoto/WhoisClient.NET/</PackageProjectUrl>

WhoisClient.NET/WhoisClient.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,15 +468,22 @@ private static async Task InvokeAsync(Func<CancellationToken, Task> action, int
468468
using (var linked = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutCancellation.Token))
469469
{
470470
#if NETCOREAPP
471-
await action(linked.Token);
471+
try
472+
{
473+
await action(linked.Token);
474+
}
475+
catch (OperationCanceledException) when (!token.IsCancellationRequested)
476+
{
477+
throw new TimeoutException("Socket operation timeout");
478+
}
472479
#else
473480
var mainTask = action(linked.Token);
474481
var timeoutTask = Task.Delay(Timeout.Infinite, timeoutCancellation.Token);
475482
var cancellationTask = Task.Delay(Timeout.Infinite, token);
476483

477484
var firstCompletedTask = await Task.WhenAny(mainTask, timeoutTask, cancellationTask);
478485

479-
if (firstCompletedTask == timeoutTask) throw new TimeoutException();
486+
if (firstCompletedTask == timeoutTask) throw new TimeoutException("Socket operation timeout");
480487
if (firstCompletedTask == cancellationTask) token.ThrowIfCancellationRequested();
481488
#endif
482489
}

0 commit comments

Comments
 (0)