HappyPath 1.3.0

dotnet add package HappyPath --version 1.3.0
                    
NuGet\Install-Package HappyPath -Version 1.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HappyPath" Version="1.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HappyPath" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="HappyPath" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add HappyPath --version 1.3.0
                    
#r "nuget: HappyPath, 1.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package HappyPath@1.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=HappyPath&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=HappyPath&version=1.3.0
                    
Install as a Cake Tool

HappyPath

Focus on the happy path - stop using exceptions and if statements to control the flow in your code! With this approach your code can be much shorter, making it easier to understand and maintain.

Tricks that allows to achieve this are:

  • Stop using exceptions to represent errors - return Result<T> from all methods.
  • Implement flow as a chain of methods.
  • Stop using null to represent the lack of a value.

Features

  1. Type that represents the result of an operation - Result<T>. The variable of that type can store either data of type T or an Error.
  2. Error - the base class for errors returned from methods. It support nesting/aggregate errors.
  3. Set of Then methods, which allows to invoke next operation on Result<T>.
  4. Result.None - represents the lack of a value returned from a method.
  5. Set of Act<T> methods, which allows to invoke an action if the result of the previous operation is T.
  6. Set of Swap<T> methods, which allows to swap the result type if the result of the previous operation is T.
  7. Match<T> method, which handles both success and error cases and returns a value of another type T. This ends the Result<> chain.
  8. async support - all Then, Act, and Swap methods have async overrides.

What is not implemented

  1. Methods like:
    1. return AbstractResultFactoryBeanImpl.CreateResultOf<string>(...)
    2. return Result.Of<string>(...)
    3. return new Result<string>(...)
  2. No result.IsError - the goal of this library is to prevent people from using if statements, so such a property would make no sense.
  3. No result.IsValid or result.IsSuccess - these are even worse than IsError, because errors needs special handling, not valid results!
  4. No parameterless constructors available for users to prevent from creating uninitialized results.

Migration

Introducing Result<T>

Let's take a method:

public static string ReverseString(string input)
{
	if (string.IsNullOrWhiteSpace(input))
	{
		throw new ArgumentException(nameof(input));
	}

	return new string(input.Reverse().ToArray());
}

With HappyPath we only need to replace throwing exceptions with returning an Error:

public static Result<string> ReverseString(string input)
{
	if (string.IsNullOrWhiteSpace(input))
	{
		return new Error(ErrorMessage);
	}

	return new string(input.Reverse().ToArray());
}

No need to change valid cases or wrapping anything in Result<T>.

Flow simplification

We can convert this:

public string ProcessAnimal(Guid id)
{
	Animal animal = null!;
	try
	{
		animal = GetRandomPetFromOracle();
	}
	catch (ThisParrotIsDeadException pe)
	{
		errorMessage = pe.Message;
		animal = new Cat("Kitty");
	}
	catch (Exception e)
	{
		errorMessage = e.Message;
	}

	if (animal is Dog d)
	{
		isPies = true;
		animal = new Cat(d.Name);
	}

	var result = TestService.ToUpperCase($"{animal.GetType().Name} is {animal.Name}");
	return result;
}

to more concise and "fluent" version:

public Result<string> ProcessAnimal(Guid id)
{
	return GetRandomPetFromOracle()
		.Act<Error>(e => errorMessage = e.Message)
		.Act<Dog>(d => isDog = true)
		.Swap<ThisParrotIsDeadError>(e => new Cat("Kitty"))
		.Swap<Dog>(d => new Cat(d.Name))
		.Then(c => TestService.ToUpperCase($"{c.GetType().Name} is {c.Name}"));
}

Of course, the GetPetFromOracle method must return Result<Animal> and use errors instead of exceptions, but this is an easy migration as shown before.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on HappyPath:

Package Downloads
HappyPath.AwesomeAssertions

AwesomeAssertions extensions for HappyPath Result type - fluent assertions for Result<T> and Error types.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.0 169 2/10/2026
1.2.0 149 2/9/2026
1.1.0 138 1/20/2026
1.0.1 335 9/18/2025
1.0.0 220 9/12/2025