Skip to content

Commit

Permalink
Fix an issue with WithTimeouts where the finally can fail if hte stre…
Browse files Browse the repository at this point in the history
…am is in an error state and potentially hide / rethrow the original error causing confusion about the source of the error. (#563)
  • Loading branch information
nathanwoctopusdeploy authored Dec 4, 2023
1 parent 97df1d6 commit 0d8ea76
Showing 1 changed file with 66 additions and 8 deletions.
74 changes: 66 additions & 8 deletions source/Halibut/Transport/Protocol/StreamTimeoutExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static async Task WithTimeout(this Stream stream, SendReceiveTimeout? tim

var currentReadTimeout = stream.ReadTimeout;
var currentWriteTimeout = stream.WriteTimeout;
var timeoutsReverted = false;

try
{
Expand All @@ -26,8 +27,20 @@ public static async Task WithTimeout(this Stream stream, SendReceiveTimeout? tim
}
finally
{
stream.ReadTimeout = currentReadTimeout;
stream.WriteTimeout = currentWriteTimeout;
try
{
stream.ReadTimeout = currentReadTimeout;
stream.WriteTimeout = currentWriteTimeout;
timeoutsReverted = true;
}
catch
{
}
}

if (!timeoutsReverted)
{
throw new InvalidOperationException("Could not revert the Timeouts. This should not happen.");
}
}

Expand All @@ -40,17 +53,33 @@ public static async Task<T> WithTimeout<T>(this Stream stream, SendReceiveTimeou

var currentReadTimeout = stream.ReadTimeout;
var currentWriteTimeout = stream.WriteTimeout;
var timeoutsReverted = false;
T result;

try
{
stream.SetReadAndWriteTimeouts(timeout);
return await func();
result = await func();
}
finally
{
stream.ReadTimeout = currentReadTimeout;
stream.WriteTimeout = currentWriteTimeout;
try
{
stream.ReadTimeout = currentReadTimeout;
stream.WriteTimeout = currentWriteTimeout;
timeoutsReverted = true;
}
catch
{
}
}

if (!timeoutsReverted)
{
throw new InvalidOperationException("Could not revert the Timeouts. This should not happen.");
}

return result;
}

public static async Task WithReadTimeout(this Stream stream, TimeSpan timeout, Func<Task> func)
Expand All @@ -63,6 +92,7 @@ public static async Task WithReadTimeout(this Stream stream, TimeSpan timeout, F
}

var currentReadTimeout = stream.ReadTimeout;
var timeoutsReverted = false;

try
{
Expand All @@ -71,7 +101,19 @@ public static async Task WithReadTimeout(this Stream stream, TimeSpan timeout, F
}
finally
{
stream.ReadTimeout = currentReadTimeout;
try
{
stream.ReadTimeout = currentReadTimeout;
timeoutsReverted = true;
}
catch
{
}
}

if (!timeoutsReverted)
{
throw new InvalidOperationException("Could not revert the Timeouts. This should not happen.");
}
}

Expand All @@ -83,16 +125,32 @@ public static async Task<T> WithReadTimeout<T>(this Stream stream, TimeSpan time
}

var currentReadTimeout = stream.ReadTimeout;
var timeoutsReverted = false;
T result;

try
{
stream.SetReadTimeouts(timeout);
return await func();
result = await func();
}
finally
{
stream.ReadTimeout = currentReadTimeout;
try
{
stream.ReadTimeout = currentReadTimeout;
timeoutsReverted = true;
}
catch
{
}
}

if (!timeoutsReverted)
{
throw new InvalidOperationException("Could not revert the Timeouts. This should not happen.");
}

return result;
}

public static void SetReadAndWriteTimeouts(this Stream stream, SendReceiveTimeout? timeout)
Expand Down

0 comments on commit 0d8ea76

Please sign in to comment.