Skip to content

Commit b4771e5

Browse files
authored
Added new "exception" optional parameter (#344)
* Added New Optional Parameter : customException A custom exception can be supplied to the guard clause methods to throw it instead of the default exception * Added new "exception" optional parameter A custom exception can be supplied to the guard clause methods to throw it instead of the default exception * renamed customException to just exception * Added Unit Tests for optional Custom Exception parameter Also fixed a few named arguments missing from method calls that i found through running the tests
1 parent 04f0487 commit b4771e5

File tree

46 files changed

+1036
-195
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1036
-195
lines changed

src/GuardClauses/GuardAgainstEmptyOrWhiteSpaceExtensions.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,49 @@ public static partial class GuardClauseExtensions
66
{
77
#if NET5_0_OR_GREATER
88
/// <summary>
9-
/// Throws an <see cref="ArgumentException" /> if <paramref name="input" /> is an empty string.
9+
/// Throws an <see cref="ArgumentException" /> or a custom <see cref="Exception" /> if <paramref name="input" /> is an empty string.
1010
/// </summary>
1111
/// <param name="guardClause"></param>
1212
/// <param name="input"></param>
1313
/// <param name="parameterName"></param>
1414
/// <param name="message">Optional. Custom error message</param>
15+
/// <param name="exception">Optional. Custom exception</param>
1516
/// <returns><paramref name="input" /> if the value is not an empty string.</returns>
1617
/// <exception cref="ArgumentException"></exception>
18+
/// <exception cref="Exception"></exception>
19+
1720
public static ReadOnlySpan<char> Empty(this IGuardClause guardClause,
1821
ReadOnlySpan<char> input,
1922
string parameterName,
20-
string? message = null)
23+
string? message = null,
24+
Exception? exception = null)
2125
{
2226
if (input.Length == 0 || input == string.Empty)
2327
{
24-
throw new ArgumentException(message ?? $"Required input {parameterName} was empty.", parameterName);
28+
throw exception ?? new ArgumentException(message ?? $"Required input {parameterName} was empty.", parameterName);
2529
}
2630
return input;
2731
}
2832

2933
/// <summary>
30-
/// Throws an <see cref="ArgumentException" /> if <paramref name="input" /> is an empty or white space string.
34+
/// Throws an <see cref="ArgumentException" /> or a custom <see cref="Exception" /> if <paramref name="input" /> is an empty or white space string.
3135
/// </summary>
3236
/// <param name="guardClause"></param>
3337
/// <param name="input"></param>
3438
/// <param name="parameterName"></param>
3539
/// <param name="message">Optional. Custom error message</param>
40+
/// <param name="exception">Optional. Custom exception</param>
3641
/// <returns><paramref name="input" /> if the value is not an empty or whitespace string.</returns>
3742
/// <exception cref="ArgumentException"></exception>
3843
public static ReadOnlySpan<char> WhiteSpace(this IGuardClause guardClause,
3944
ReadOnlySpan<char> input,
4045
string parameterName,
41-
string? message = null)
46+
string? message = null,
47+
Exception? exception = null)
4248
{
4349
if (MemoryExtensions.IsWhiteSpace(input))
4450
{
45-
throw new ArgumentException(message ?? $"Required input {parameterName} was empty.", parameterName);
51+
throw exception ?? new ArgumentException(message ?? $"Required input {parameterName} was empty.", parameterName!);
4652
}
4753

4854
return input;

src/GuardClauses/GuardAgainstExpressionExtensions.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,62 @@ namespace Ardalis.GuardClauses;
77
public static partial class GuardClauseExtensions
88
{
99
/// <summary>
10-
/// Validates the <paramref name="input"/> using the specified <paramref name="func"/> and throws an <see cref="ArgumentException"/> if it evaluates to true.
10+
/// Validates the <paramref name="input"/> using the specified <paramref name="func"/> and throws an <see cref="ArgumentException"/> or a custom <see cref="Exception" /> if it evaluates to true.
1111
/// The <paramref name="func"/> should return true to indicate an invalid or undesirable state of the input.
12-
/// If <paramref name="func"/> returns true, an <see cref="ArgumentException"/> is thrown, signifying that the input is invalid.
12+
/// If <paramref name="func"/> returns true, an <see cref="ArgumentException"/> or a custom <see cref="Exception" /> is thrown, signifying that the input is invalid.
1313
/// </summary>
1414
/// <typeparam name="T">The type of the input parameter.</typeparam>
1515
/// <param name="guardClause">The guard clause instance.</param>
1616
/// <param name="func">The function that evaluates the input. It should return true if the input is considered invalid or in a negative state.</param>
1717
/// <param name="input">The input to evaluate.</param>
1818
/// <param name="message">The message to include in the exception if the input is invalid.</param>
1919
/// <param name="parameterName">The name of the parameter to include in the thrown exception, captured automatically from the input expression.</param>
20+
/// <param name="exception"></param>
2021
/// <returns>The <paramref name="input"/> if the <paramref name="func"/> evaluates to false, indicating a valid state.</returns>
2122
/// <exception cref="ArgumentException">Thrown when the validation function returns true, indicating that the input is invalid.</exception>
23+
/// <exception cref="Exception"></exception>
2224
public static T Expression<T>(this IGuardClause guardClause,
2325
Func<T, bool> func,
2426
T input,
2527
string message,
26-
[CallerArgumentExpression("input")] string? parameterName = null)
28+
[CallerArgumentExpression("input")] string? parameterName = null,
29+
Exception? exception = null)
2730
where T : struct
2831
{
2932
if (func(input))
3033
{
31-
throw new ArgumentException(message, parameterName!);
34+
throw exception ?? new ArgumentException(message, parameterName!);
3235
}
3336

3437
return input;
3538
}
3639

3740
/// <summary>
38-
/// Validates the <paramref name="func"/> asynchronously and throws an <see cref="ArgumentException" /> if it evaluates to false for given <paramref name="input"/>
41+
/// Validates the <paramref name="func"/> asynchronously and throws an <see cref="ArgumentException" /> or a custom <see cref="Exception" /> if it evaluates to false for given <paramref name="input"/>
3942
/// The <paramref name="func"/> should return true to indicate an invalid or undesirable state.
40-
/// If <paramref name="func"/> returns true, indicating that the input is invalid, an <see cref="ArgumentException"/> is thrown.
43+
/// If <paramref name="func"/> returns true, indicating that the input is invalid, an <see cref="ArgumentException"/> or a custom <see cref="Exception" /> is thrown.
4144
/// </summary>
4245
/// <typeparam name="T">The type of the input parameter.</typeparam>
4346
/// <param name="func">The function that evaluates the input. It should return true if the input is considered invalid or in a negative state.</param>
4447
/// <param name="guardClause">The guard clause instance.</param>
4548
/// <param name="input">The input to evaluate.</param>
4649
/// <param name="message">The message to include in the exception if the input is invalid.</param>
4750
/// <param name="parameterName">The name of the parameter to include in the thrown exception, captured automatically from the input expression.</param>
51+
/// <param name="exception"></param>
4852
/// <returns><paramref name="input"/> if the <paramref name="func"/> evaluates to true </returns>
4953
/// <exception cref="ArgumentException">Thrown when the validation function returns true, indicating that the input is invalid.</exception>
54+
/// <exception cref="Exception"></exception>
5055
public static async Task<T> ExpressionAsync<T>(this IGuardClause guardClause,
5156
Func<T, Task<bool>> func,
5257
T input,
5358
string message,
54-
[CallerArgumentExpression("input")] string? parameterName = null)
59+
[CallerArgumentExpression("input")] string? parameterName = null,
60+
Exception? exception = null)
5561
where T : struct
5662
{
5763
if (await func(input))
5864
{
59-
throw new ArgumentException(message, parameterName!);
65+
throw exception ?? new ArgumentException(message, parameterName!);
6066
}
6167

6268
return input;

src/GuardClauses/GuardAgainstInvalidFormatExtensions.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,71 +7,83 @@ namespace Ardalis.GuardClauses;
77
public static partial class GuardClauseExtensions
88
{
99
/// <summary>
10-
/// Throws an <see cref="ArgumentException" /> if <paramref name="input"/> doesn't match the <paramref name="regexPattern"/>.
10+
/// Throws an <see cref="ArgumentException" /> or a custom <see cref="Exception" /> if <paramref name="input"/> doesn't match the <paramref name="regexPattern"/>.
1111
/// </summary>
1212
/// <param name="guardClause"></param>
1313
/// <param name="input"></param>
1414
/// <param name="parameterName"></param>
1515
/// <param name="regexPattern"></param>
1616
/// <param name="message">Optional. Custom error message</param>
17+
/// <param name="exception"></param>
1718
/// <returns></returns>
1819
/// <exception cref="ArgumentException"></exception>
20+
/// <exception cref="Exception"></exception>
1921
public static string InvalidFormat(this IGuardClause guardClause,
2022
string input,
2123
string parameterName,
2224
string regexPattern,
23-
string? message = null)
25+
string? message = null,
26+
Exception? exception = null)
2427
{
2528
var m = Regex.Match(input, regexPattern);
2629
if (!m.Success || input != m.Value)
2730
{
28-
throw new ArgumentException(message ?? $"Input {parameterName} was not in required format", parameterName);
31+
throw exception ?? new ArgumentException(message ?? $"Input {parameterName} was not in required format", parameterName);
2932
}
3033

3134
return input;
3235
}
3336

3437
/// <summary>
35-
/// Throws an <see cref="ArgumentException" /> if <paramref name="input"/> doesn't satisfy the <paramref name="predicate"/> function.
38+
/// Throws an <see cref="ArgumentException" /> or a custom <see cref="Exception" /> if <paramref name="input"/> doesn't satisfy the <paramref name="predicate"/> function.
3639
/// </summary>
3740
/// <param name="guardClause"></param>
3841
/// <param name="input"></param>
3942
/// <param name="parameterName"></param>
4043
/// <param name="predicate"></param>
4144
/// <param name="message">Optional. Custom error message</param>
45+
/// <param name="exception"></param>
4246
/// <typeparam name="T"></typeparam>
4347
/// <returns></returns>
4448
/// <exception cref="ArgumentException"></exception>
45-
public static T InvalidInput<T>(this IGuardClause guardClause, T input, string parameterName, Func<T, bool> predicate, string? message = null)
49+
/// <exception cref="Exception"></exception>
50+
public static T InvalidInput<T>(this IGuardClause guardClause,
51+
T input, string parameterName,
52+
Func<T, bool> predicate,
53+
string? message = null,
54+
Exception? exception = null)
4655
{
4756
if (!predicate(input))
4857
{
49-
throw new ArgumentException(message ?? $"Input {parameterName} did not satisfy the options", parameterName);
58+
throw exception ?? new ArgumentException(message ?? $"Input {parameterName} did not satisfy the options", parameterName);
5059
}
5160

5261
return input;
5362
}
5463

5564
/// <summary>
56-
/// Throws an <see cref="ArgumentException" /> if <paramref name="input"/> doesn't satisfy the <paramref name="predicate"/> function.
65+
/// Throws an <see cref="ArgumentException" /> or a custom <see cref="Exception" /> if <paramref name="input"/> doesn't satisfy the <paramref name="predicate"/> function.
5766
/// </summary>
5867
/// <param name="guardClause"></param>
5968
/// <param name="input"></param>
6069
/// <param name="parameterName"></param>
6170
/// <param name="predicate"></param>
6271
/// <param name="message">Optional. Custom error message</param>
72+
/// <param name="exception"></param>
6373
/// <typeparam name="T"></typeparam>
6474
/// <returns></returns>
6575
/// <exception cref="ArgumentException"></exception>
76+
/// <exception cref="Exception"></exception>
6677
public static async Task<T> InvalidInputAsync<T>(this IGuardClause guardClause,
6778
T input,
6879
string parameterName,
6980
Func<T, Task<bool>> predicate,
70-
string? message = null)
81+
string? message = null,
82+
Exception? exception = null)
7183
{
7284
if (!await predicate(input))
7385
{
74-
throw new ArgumentException(message ?? $"Input {parameterName} did not satisfy the options", parameterName);
86+
throw exception ?? new ArgumentException(message ?? $"Input {parameterName} did not satisfy the options", parameterName);
7587
}
7688

7789
return input;

0 commit comments

Comments
 (0)