Throw
A simple, fluent, extensible, and fully customizable library for throwing exceptions for projects using .NET 6+
Install / Use
/learn @amantinband/ThrowREADME
A simple, fluent, extensible, and fully customizable library for throwing exceptions using .NET 6+
dotnet add package throw
- Give it a star ⭐!
- Nullable vs non-nullable types
- Customize everything
- Usage
- Common types
- Booleans
- Nullable value types (
bool?,int?,double?,DateTime?etc.) - Strings
- Collections (
IEnumerable,IEnumerable<T>,ICollection,ICollection<T>,IList, etc.) - DateTime
- Enums
- Equalities (non-nullables)
- Uris
- Comparable (
int,double,decimal,long,float,short,DateTime,DateOnly,TimeOnlyetc.) - Types
- Nested properties
- Common types
- Extensibility
- Conditional compilation
- Upcoming features
- Contribution
- Credits
- License
Give it a star ⭐!
Loving it? Show your support by giving this project a star!
Nullable vs non-nullable types
This library is designed to work best with nullable reference types feature enabled.
The Throw() method is the entry method for all non-nullable types:
string name = "hello";
name.Throw().IfLongerThan(10);
And ThrowIfNull() for any nullable type:
string? name = "hello";
name.ThrowIfNull();
Trying to use Throw() on a nullable type will give a warning
string? name = null;
name.Throw() // warning CS8714: The type 'string?' cannot be used as type parameter 'TValue' in the generic type or method 'ValidatableCreationExtensions.Throw<TValue>(TValue, ExceptionCustomizations?, string?)'. Nullability of type argument 'string?' doesn't match 'notnull' constraint.
.IfEmpty();
After validating that the nullable type isn't null, all the regular non-nullable rules can be used
name.ThrowIfNull()
.IfEmpty()
.IfLongerThan(3);
The expression can be implicitly cast to the non-nullable type of the original nullable type
string? name = "Amichai";
string nonNullableName = name.ThrowIfNull()
.IfEmpty()
.IfLongerThan(10);
or
int? a = 5;
int b = a.ThrowIfNull();
Customize everything
How customizing the exception affects the chained rules
If you have customized the exception, any rule that throws an exception will use the customization. For example:
// Default behavior:
name.Throw()
.IfEmpty() // System.ArgumentException: String should not be empty. (Parameter 'name')
.IfWhiteSpace() // System.ArgumentException: String should not be white space only. (Parameter 'name')
.IfLongerThan(3) // System.ArgumentException: String should not be longer than 3 characters. (Parameter 'name')
.IfShorterThan(10); // System.ArgumentException: String should not be shorter than 10 characters. (Parameter 'name')
// Customized behavior:
name.Throw(paramName => throw new MyCustomException($"Param name: {paramName}."))
.IfEmpty() // MyCustomException: Param name: name.
.IfWhiteSpace() // MyCustomException: Param name: name.
.IfLongerThan(3) // MyCustomException: Param name: name.
.IfShorterThan(10); // MyCustomException: Param name: name.
At any point, you can change the exception customization, and it will apply for all the rules that follow. For example:
name.Throw("String should not be empty or white space only.")
.IfEmpty() // System.ArgumentException: String should not be empty or white space only. (Parameter 'name')
.IfWhiteSpace() // System.ArgumentException: String should not be empty or white space only. (Parameter 'name')
.Throw("String should not be between 3 and 10 characters long.")
.IfLongerThan(3) // System.ArgumentException: String should not be between 3 and 10 characters long. (Parameter 'name')
.IfShorterThan(10); // System.ArgumentException: String should not be between 3 and 10 characters long. (Parameter 'name')
To go back to the default exception, simply use the Throw() method. For example:
name.Throw("String should not be empty or white space only.")
.IfEmpty() // System.ArgumentException: String should not be empty or white space only. (Parameter 'name')
.IfWhiteSpace() // System.ArgumentException: String should not be empty or white space only. (Parameter 'name')
.Throw()
.IfLongerThan(3) // System.ArgumentException: String should not be longer than 3 characters. (Parameter 'name')
.IfShorterThan(10); // System.ArgumentException: String should not be shorter than 10 characters. (Parameter 'name')
Exception customizations
1. Throw()
Each rule has a default behavior. If you don't customize the exception, the default behavior will be used.
Use the Throw() or ThrowIfNull() method to throw the default exception
// ArgumentNullException: Value cannot be null. (Parameter 'nullableValue')
nullableValue.ThrowIfNull();
// System.ArgumentOutOfRangeException: Value should not be less than 2/28/2042 4:41:46 PM. (Parameter 'dateTime')\n Actual value was 2/28/2022 4:41:46 PM.
dateTime.Throw().IfLessThan(DateTime.Now.AddYears(20));
// ArgumentException: Value should not be true (Parameter 'isGood')
isGood.Throw().IfTrue();
// System.ArgumentException: String should not be empty. (Parameter 'name')
name.Throw().IfEmpty();
// System.ArgumentOutOfRangeException: Value should not be greater than 0. (Parameter 'number')\n Actual value was 5.
number.Throw().IfPositive();
2. Throw("My custom message")
Pass a custom exception message to the Throw() or ThrowIfNull() method
// System.ArgumentNullException: My custom message (Parameter 'nullableValue')
nullableValue.ThrowIfNull("My custom message");
// System.ArgumentOutOfRangeException: My custom message (Parameter 'dateTime')\n Actual value was 3/1/2022 10:47:15 AM.
dateTime.Throw("My custom message").IfLessThan(DateTime.Now.AddYears(20));
// System.ArgumentException: My custom message (Parameter 'isGood')
isGood.Throw("My custom message").IfTrue();
// System.ArgumentException: My custom message (Parameter 'name')
name.Throw("My custom message").IfEmpty();
// System.ArgumentOutOfRangeException: My custom message (Parameter 'number')\n Actual value was 5.
number.Throw("My custom message").IfPositive();
3. Throw(() => new MyException())
Pass a custom exception thrower to the Throw() or ThrowIfNull() method
// MyCustomException: Exception of type 'MyCustomException' was thrown.
nullableValue.ThrowIfNull(() => throw new MyCustomException());
// MyCustomException: Exception of type 'MyCustomException' was thrown.
dateTime.Throw(() => throw new MyCustomException()).IfLessThan(DateTime.Now.AddYears(20));
// MyCustomException: Exception of type 'MyCustomException' was thrown.
isGood.Throw(() => throw new MyCustomException()).IfTrue();
// MyCustomException: Exception of type 'MyCustomException' was thrown.
name.Throw(() => throw new MyCustomException()).IfEmpty();
// MyCustomException: Exception of type 'MyCustomException' was thrown.
number.Throw(() => throw new MyCustomException()).IfPositive();
4. Throw(paramName => new MyException($"Param: {paramName}")
Pass a custom exception thrower to the Throw() or ThrowIfNull() method, that takes the parameter name as a parameter
This comes in handy in scenarios like this:
void SendEmail(User user)
{
user.Throw(paramName => new UserException(message: "Cannot send email since use
Related Skills
OpenMetadata
9.1kOpenMetadata is a unified metadata platform for data discovery, data observability, and data governance powered by a central metadata repository, in-depth column level lineage, and seamless team collaboration.
A2V
1.2kA2V: Next-Gen AI Value Compute Protocol.
rust-mcp-core
7A config-driven MCP server core built on the official Rust SDK. Define tools, auth, prompts, resources, and HTTP behavior in YAML or JSON configuration -- the library handles execution, validation, and protocol compliance with minimal Rust code.
korean-law-mcp
88387 tools for Korean law — statutes, precedents, ordinances, interpretations | MCP Server · CLI · npm

