NocturnalGroup.Outcome 1.0.0-preview.2

This is a prerelease version of NocturnalGroup.Outcome.
dotnet add package NocturnalGroup.Outcome --version 1.0.0-preview.2                
NuGet\Install-Package NocturnalGroup.Outcome -Version 1.0.0-preview.2                
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="NocturnalGroup.Outcome" Version="1.0.0-preview.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add NocturnalGroup.Outcome --version 1.0.0-preview.2                
#r "nuget: NocturnalGroup.Outcome, 1.0.0-preview.2"                
#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.
// Install NocturnalGroup.Outcome as a Cake Addin
#addin nuget:?package=NocturnalGroup.Outcome&version=1.0.0-preview.2&prerelease

// Install NocturnalGroup.Outcome as a Cake Tool
#tool nuget:?package=NocturnalGroup.Outcome&version=1.0.0-preview.2&prerelease                

<img align="right" width="256" height="256" src="Assets/Logo.png">

<div id="user-content-toc"> <ul align="center" style="list-style: none;"> <summary> <h1>Outcome</h1> </summary> </ul> </div>

Return types for problematic functions


Outcome is a set of types used to implement the result pattern.

Why?

In our opinion, exceptions are annoying to deal with. The try catch mechanism is ugly, and there's no way to tell if a function throws an exception. Most errors aren't "exceptional" and don't justify the resource cost of an exception. They should be saved for critical problems. The Outcome types are much lighter and can provide a better error handling experience.

Installing

You can install the package from NuGet:

dotnet add package NocturnalGroup.Outcome

Usage

A complete example of how to use the Outcome library can be found in the samples directory.

Producing

The Outcome library provides the Outcome<TValue> type, which represents the outcome of an operation. An operation is either successful or fails, which is the two states an Outcome<TValue> can be. So if your method can throw an error, return an Outcome<TValue>.

Outcome<TValue> provides some implicit operators. This allows you to return an Error and have it turned into an `Outcome<TValue> automatically.

Outcome<User> CreateUser(string username)
{
  var userExists = // .. Check for the user ..
  if (userExists)
  {
    return new Error("user already exists"); // or new Outcome<User>(new Error(...)).
  }

  // .. Do some work ..
  return user; // or new Outcome<User>(user).
}

You can also provide your own error type.

public enum CreateUserError { UsernameTaken, ConnectionError }

Outcome<User, CreateUserError> CreateUser(string username)
{
  // ...
  if (userExists)
  {
    return CreateUserError.UsernameTaken;
  }
  // ...
}

Consuming

Consuming the outcome can be done in one of two ways.

The first way is to access the type normally. This gives you access to various helpers, such as the Success and Failed properties.

var createOperation = userService.CreateUser("Nocturnal");
if (createOperation.Failed)
{
  Console.WriteLine($"Failed to create user ({createOperation.Error.Message})");
  return;
}

Console.Out.WriteLine("User was created!");

The second way is to use Deconstructing. This allows you to access the values directly, somewhat similar to Golang's error handling.

var (user, error) = userService.CreateUser("Nocturnal");
// or
var (status, user, error) = userService.CreateUser("Nocturnal");

Pain Points

There's no getting around that the standard library is designed with exceptions in mind. So by using this library, you will still have to think about exceptions.

Versioning

Outcome follows the SemVer versioning scheme.

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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-preview.2 37 1/17/2025
1.0.0-preview.1 32 1/17/2025