NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
NuGet · #2522 most downloaded on NuGet
A simple, fluent discriminated union of an error or a result.
Last release 4 months ago
15 May 2026
Ships unpredictably
gaps range from 1 weeks to 2.1 years
Rarely documented
notes for 4 of 19 stable releases
5 versions withdrawn
withdrawn after publishing
127 years old
24 releases · first in 1900
new Release with many new features:
new Release with many new features:
FailIf methodsFailIf method overloads that allow to use value in error definition using Func<TValue, Error> error builderElseDo and ElseDoAsync methodsElse/ElseAsync overloads returning ErrorOrElse/ElseAsync overloads returning ErrorOrToErrorOrAsync methodErrorOrFactory.From methodsFromAsync and missing ToErrorOrAsync methodsThenEnsure and ThenEnsureAsync methodsIsSuccess property to ErrorOr#94, #95 Added missing async versions of FailIf methods
public async Task<ErrorOr<TValue>> FailIfAsync(Func<TValue, Task<bool>> onValue, Error error)
public static async Task<ErrorOr<TValue>> FailIf<TValue>(
this Task<ErrorOr<TValue>> errorOr,
Func<TValue, bool> onValue,
Error error)
public static async Task<ErrorOr<TValue>> FailIfAsync<TValue>(
this Task<ErrorOr<TValue>> errorOr,
Func<TValue, Task<bool>> onValue,
Error error)
#104 Support for .NET 8 was added
#109, #111 Added FailIf method overloads that allow to use value in error definition using Func<TValue, Error> error builder
public ErrorOr<TValue> FailIf(Func<TValue, bool> onValue, Func<TValue, Error> errorBuilder)
public async Task<ErrorOr<TValue>> FailIfAsync(Func<TValue, Task<bool>> onValue, Func<TValue, Task<Error>> errorBuilder)
public static async Task<ErrorOr<TValue>> FailIf<TValue>(
this Task<ErrorOr<TValue>> errorOr,
Func<TValue, bool> onValue,
Func<TValue, Error> errorBuilder)
public static async Task<ErrorOr<TValue>> FailIfAsync<TValue>(
this Task<ErrorOr<TValue>> errorOr,
Func<TValue, Task<bool>> onValue,
Func<TValue, Task<Error>> errorBuilder)
Value can now be used to build the error:
ErrorOr<int> result = errorOrInt
.FailIf(num => num > 3, (num) => Error.Failure(description: $"{num} is greater than 3"));
#117 Added ElseDo and ElseDoAsync methods
Actions returning no result can now be called when IsError is true.
ErrorOr<string> foo = result
.Else(errors => Error.Unexpected())
.ElseDo(error => Console.WriteLine(error.FirstError.Description));
ErrorOr<string> foo = await result
.ElseDoAsync(HandleErrorAsync);
#122 Added ToErrorOrAsync method
Values in Task can now be easily converted to ErrorOr.
ErrorOr<int> result = await Task.FromResult(5).ToErrorOrAsync();
#129 Added missing ErrorOrFactory.From methods
Now following calls from README.md are available
ErrorOr<int> result = ErrorOrFactory.From<int>(Error.Unexpected());
ErrorOr<int> result = ErrorOrFactory.From<int>([Error.Validation(), Error.Validation()]);
Following call is now obsolete
ErrorOr<int> errorOrPerson = ErrorOr<int>.From([Error.Validation(), Error.Validation()]);
#133 Added missing collection expression support
Now following call from README.md is available
ErrorOr<int> result = [Error.Validation(), Error.Validation()];
#134 Added FromAsync and missing ToErrorOrAsync methods
Added support for FromAsync methods.
public async Tak<ErrorOr<int>> GetValueAsync()
{
return await ErrorOrFactory.FromAsync(5);
}
public async Tak<ErrorOr<int>> SingleErrorToErrorOrAsync()
{
return await ErrorOrFactory.FromAsync<int>(Error.Unexpected());
}
public async Tak<ErrorOr<int>> MultipleErrorsToErrorOrAsync()
{
return await ErrorOrFactory.FromAsync([
Error.Validation(description: "Invalid Name"),
Error.Validation(description: "Invalid Last Name")
]);
}
Added support for ToErrorOrAsync methods from errors:
Task<Error> errorTask = Task.FromResult(Error.Validation());
ErrorOr<int> result = errorTask.ToErrorOrAsync<int>();
List<Error> errors = [Error.Unauthorized(), Error.Validation()];
Task<List<Error>> errorsTask = Task.FromResult(errors);
ErrorOr<int> result = await errorsTask.ToErrorOrAsync<int>();
#149 Added Else/ElseAsync overloads returning ErrorOr
#152 Added ThenEnsure and ThenEnsureAsync methods.
They are similar to ThenDo and ThenDoAsync, but they receive a function that can return errors.
If no errors are returned, the original value is preserved and the ensure function's success value is ignored.
#159 Added IsSuccess property to ErrorOr
#158 Added support for serialization via IErrorOr interface without direct access to Value property. The IRecordable base interface provides a way to obtain a serialized representation of the current state.
void Log(IErrorOr result)
{
Console.WriteLine(result.GetRecording(serializer));
}
IRecordingSerializer<TOutput> interface can be implemented to provide concrete serialization strategy, for exaple JSON serialization:
using System.Text.Json;
using System.Text.Json.Serialization;
using ErrorOr;
public class SystemTextJsonRecordingSerializer : IRecordingSerializer<string>
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
Converters = { new JsonStringEnumConverter() },
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
};
public string SerializeValue<TValue>(TValue value)
=> JsonSerializer.Serialize(value, JsonOptions);
public string SerializeErrors(List<Error> errors)
=> JsonSerializer.Serialize(errors, JsonOptions);
}
#179 Support for .NET 10 was added
#85, #97 ErrorOr turned into Value Object by reimplementing Equals and GetHashCode methods
New dependency was introduced to Microsoft.Bcl.HashCode and development dependency was introduced to Nullable
#178 Initializing ErrorOr<T> with empty or null error collection results with unexpected error.
One column per quarter.
Nothing published for this version
Then that receives an action is now called ThenDo
Then that receives an action is now called ThenDo
-public ErrorOr<TValue> Then(Action<TValue> action)
+public ErrorOr<TValue> ThenDo(Action<TValue> action)
-public static async Task<ErrorOr<TValue>> Then<TValue>(this Task<ErrorOr<TValue>> errorOr, Action<TValue> action)
+public static async Task<ErrorOr<TValue>> ThenDo<TValue>(this Task<ErrorOr<TValue>> errorOr, Action<TValue> action)
ThenAsync that receives an action is now called ThenDoAsync
-public async Task<ErrorOr<TValue>> ThenAsync(Func<TValue, Task> action)
+public async Task<ErrorOr<TValue>> ThenDoAsync(Func<TValue, Task> action)
-public static async Task<ErrorOr<TValue>> ThenAsync<TValue>(this Task<ErrorOr<TValue>> errorOr, Func<TValue, Task> action)
+public static async Task<ErrorOr<TValue>> ThenDoAsync<TValue>(this Task<ErrorOr<TValue>> errorOr, Func<TValue, Task> action)
FailIf
public ErrorOr<TValue> FailIf(Func<TValue, bool> onValue, Error error)
ErrorOr<int> errorOr = 1;
errorOr.FailIf(x => x > 0, Error.Failure());
Nothing published for this version
Features 🚀 Forbidden Error Type ( #86 ) README to NuGet package
Features 🚀 ToErrorOr ( #83 ) Fixed 🔧 Added Missing tests
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →