SkillAgentSearch skills...

Throw

A simple, fluent, extensible, and fully customizable library for throwing exceptions for projects using .NET 6+

Install / Use

/learn @amantinband/Throw
About this skill

Quality Score

0/100

Category

Legal

Supported Platforms

Universal

README

<div align="center"> <img src="assets/icon.png" alt="drawing" width="700px"/>

NuGet

Build publish Throw to NuGet codecov

GitHub contributors GitHub Stars GitHub license


A simple, fluent, extensible, and fully customizable library for throwing exceptions using .NET 6+

dotnet add package throw

Getting started png

</div>

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

View on GitHub
GitHub Stars1.3k
CategoryLegal
Updated4d ago
Forks86

Languages

C#

Security Score

100/100

Audited on Mar 27, 2026

No findings