mirror of
https://github.com/Stone-Red-Code/CuteUtils.git
synced 2026-09-04 08:56:13 +02:00
Add rename SafeRetry to Try and add Catch methods
This commit is contained in:
@@ -1,222 +0,0 @@
|
||||
using CuteUtils.Misc;
|
||||
|
||||
namespace CuteUtils.Tests.Misc;
|
||||
|
||||
[TestClass]
|
||||
public class SafeRetryTests
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
await Task.Delay(10);
|
||||
return 42;
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
Assert.AreEqual(42, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 3)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
await Task.Delay(10);
|
||||
return 99;
|
||||
}, maxRetries: 5, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(3, callCount);
|
||||
Assert.AreEqual(99, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = await Assert.ThrowsExceptionAsync<InvalidOperationException>(async () =>
|
||||
{
|
||||
_ = await SafeRetry.RetryAsync<int>(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new InvalidOperationException("fail");
|
||||
}, maxRetries: 2, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
await Task.Delay(10);
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 2)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
await Task.Delay(10);
|
||||
}, maxRetries: 3, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = await Assert.ThrowsExceptionAsync<InvalidOperationException>(async () =>
|
||||
{
|
||||
await SafeRetry.RetryAsync(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new Exception();
|
||||
}, maxRetries: 2, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
return 7;
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
Assert.AreEqual(7, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 4)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
return 123;
|
||||
}, maxRetries: 5, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(4, callCount);
|
||||
Assert.AreEqual(123, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
_ = SafeRetry.Retry<int>(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new Exception();
|
||||
}, maxRetries: 3, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(3, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 2)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}, maxRetries: 3, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new Exception();
|
||||
}, maxRetries: 2, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
|
||||
{
|
||||
_ = await SafeRetry.RetryAsync<int>(null!);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
|
||||
{
|
||||
await SafeRetry.RetryAsync(null!);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = Assert.ThrowsException<ArgumentNullException>(() =>
|
||||
{
|
||||
_ = SafeRetry.Retry<int>(null!);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = Assert.ThrowsException<ArgumentNullException>(() =>
|
||||
{
|
||||
SafeRetry.Retry(null!);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
namespace CuteUtils.Misc;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace CuteUtils.Misc;
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for safely retrying actions and functions with optional delay and retry count.
|
||||
/// </summary>
|
||||
public static class SafeRetry
|
||||
public static class Try
|
||||
{
|
||||
/// <summary>
|
||||
/// Retries an asynchronous function returning a value, up to a specified number of times, with an optional delay between attempts.
|
||||
@@ -127,4 +129,155 @@ public static class SafeRetry
|
||||
}
|
||||
throw new InvalidOperationException($"Failed after {maxRetries} attempts.", lastException);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a synchronous action and catches any exception, writing it to the debug output.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute.</param>
|
||||
public static void Catch(Action action)
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a synchronous action and catches any exception, writing it to the debug output and returning it via an out parameter.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute.</param>
|
||||
/// <param name="exception">When this method returns, contains the exception that was thrown, or null if no exception was thrown.</param>
|
||||
public static void Catch(Action action, out Exception? exception)
|
||||
{
|
||||
exception = null;
|
||||
try
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a synchronous function and catches any exception, writing it to the debug output. Returns the default value if an exception occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The return type of the function.</typeparam>
|
||||
/// <param name="action">The function to execute.</param>
|
||||
/// <returns>The result of the function, or the default value of <typeparamref name="T"/> if an exception occurs.</returns>
|
||||
public static T? Catch<T>(Func<T> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a synchronous function and catches any exception, writing it to the debug output and returning the exception via an out parameter.
|
||||
/// Returns the default value if an exception occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The return type of the function.</typeparam>
|
||||
/// <param name="action">The function to execute.</param>
|
||||
/// <param name="exception">When this method returns, contains the exception that was thrown, or null if no exception was thrown.</param>
|
||||
/// <returns>The result of the function, or the default value of <typeparamref name="T"/> if an exception occurs.</returns>
|
||||
public static T? Catch<T>(Func<T> action, out Exception? exception)
|
||||
{
|
||||
exception = null;
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
exception = ex;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes an asynchronous action and catches any exception, writing it to the debug output.
|
||||
/// </summary>
|
||||
/// <param name="action">The asynchronous action to execute.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public static async Task CatchAsync(Func<Task> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes an asynchronous function and catches any exception, writing it to the debug output.
|
||||
/// Returns the default value if an exception occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The return type of the function.</typeparam>
|
||||
/// <param name="action">The asynchronous function to execute.</param>
|
||||
/// <returns>The result of the function, or the default value of <typeparamref name="T"/> if an exception occurs.</returns>
|
||||
public static async Task<T?> CatchAsync<T>(Func<Task<T>> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for an asynchronous task to complete and catches any exception, writing it to the debug output.
|
||||
/// </summary>
|
||||
/// <param name="task">The task to await.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public static async Task CatchAsync(Task task)
|
||||
{
|
||||
try
|
||||
{
|
||||
await task;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for an asynchronous task that returns a result and catches any exception, writing it to the debug output.
|
||||
/// Returns the default value if an exception occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The return type of the task.</typeparam>
|
||||
/// <param name="task">The task to await.</param>
|
||||
/// <returns>The result of the task, or the default value of <typeparamref name="T"/> if an exception occurs.</returns>
|
||||
public static async Task<T?> CatchAsync<T>(Task<T> task)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await task;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user