MisterMoret.Try 1.0.0-beta.3

This is a prerelease version of MisterMoret.Try.
dotnet add package MisterMoret.Try --version 1.0.0-beta.3
                    
NuGet\Install-Package MisterMoret.Try -Version 1.0.0-beta.3
                    
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="MisterMoret.Try" Version="1.0.0-beta.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MisterMoret.Try" Version="1.0.0-beta.3" />
                    
Directory.Packages.props
<PackageReference Include="MisterMoret.Try" />
                    
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 MisterMoret.Try --version 1.0.0-beta.3
                    
#r "nuget: MisterMoret.Try, 1.0.0-beta.3"
                    
#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 MisterMoret.Try@1.0.0-beta.3
                    
#: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=MisterMoret.Try&version=1.0.0-beta.3&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=MisterMoret.Try&version=1.0.0-beta.3&prerelease
                    
Install as a Cake Tool

MisterMoret.Try

License: MIT NuGet .NET 8.0 .NET 9.0 .NET 10.0 NuGet GitHub

A lightweight try/catch wrapper that converts unhandled exceptions into failed Result or HttpResult objects, eliminating boilerplate exception handling in .NET applications.

This package is currently in beta and available via NuGet.org.

✨ Features

  • Exception-Safe Execution: Wrap any synchronous or asynchronous delegate and receive a failed result instead of a thrown exception.
  • Result Integration: Works seamlessly with MisterMoret.Results β€” returns Result<T>, Result, HttpResult<T>, and HttpResult.
  • HTTP-Aware: Maps HTTP-related exceptions to meaningful HttpStatusCode values automatically.
  • Auto-Wrapping: Pass a plain Func<Task<T>> and let the library wrap the return value in a result for you.
  • Custom Error Messages: Supply an optional exceptionMapper delegate to control the error message on failure instead of using Exception.Message.
  • Zero Boilerplate: Import the namespace once and call methods directly via the class name.
  • Modern .NET Support: Targets .NET 8.0, 9.0, and 10.0.

πŸš€ Installation

Install the package via the NuGet CLI:

dotnet add package MisterMoret.Try --version 1.0.0-beta.3

πŸ’‘ Usage

Add a using directive to bring the classes into scope:

using MisterMoret.Try;

TryOperation β€” Result Overloads

Use when you want a Result or Result<T> back. Both synchronous and asynchronous delegates are supported.

Asynchronous (ExecuteAsync)

Auto-wrapping β€” pass a plain delegate and the result is created for you:

// Returns Result<User>
var result = await TryOperation.ExecuteAsync(() => _repository.GetUserAsync(id));

if (result.IsSuccess)
{
    Console.WriteLine(result.Value.Name);
}
else
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine($"Error: {error}");
    }
}

Manual result β€” use when you need to return a failure or perform validation inside the delegate:

var result = await TryOperation.ExecuteAsync(async () =>
{
    var user = await _repository.GetUserAsync(id);
    if (user == null)
        return Result<User>.Failure("User not found.");
    return Result<User>.Success(user);
});
Synchronous (Execute)

Use the same patterns with synchronous delegates when async is not needed:

Auto-wrapping β€” wraps the return value in Result<T>.Success:

// Returns Result<User>
var result = TryOperation.Execute(() => _repository.GetUser(id));

if (result.IsSuccess)
{
    Console.WriteLine(result.Value.Name);
}
else
{
    foreach (var error in result.Errors)
    {
        Console.WriteLine($"Error: {error}");
    }
}

Manual result β€” use when you need to return a failure or perform validation inside the delegate:

var result = TryOperation.Execute(() =>
{
    var user = _repository.GetUser(id);
    if (user == null)
        return Result<User>.Failure("User not found.");
    return Result<User>.Success(user);
});

Void action β€” wraps a side-effecting operation in Result.Success:

var result = TryOperation.Execute(() => _repository.DeleteUser(id));

if (!result.IsSuccess)
{
    Console.WriteLine(string.Join(", ", result.Errors));
}
Custom Error Messages (exceptionMapper)

All TryOperation overloads accept an optional Func<Exception, string>? exceptionMapper parameter. When supplied, the delegate produces the error message on failure instead of Exception.Message. The parameter is positional, so pass it after the operation delegate:

var result = await TryOperation.ExecuteAsync(
    () => _repository.GetUserAsync(id),
    ex => $"Failed to load user {id}: {ex.GetType().Name}");

if (!result.IsSuccess)
{
    Console.WriteLine(result.Errors[0]); // "Failed to load user 42: InvalidOperationException"
}

When exceptionMapper is omitted or null, the behaviour is unchanged β€” Exception.Message is used.

TryHttpOperation.ExecuteAsync β€” HttpResult Overloads

Use when you want an HttpResult or HttpResult<T> back. HTTP-related exceptions are mapped to appropriate status codes automatically.

Auto-wrapping β€” success defaults to 200 OK:

// Returns HttpResult<User>
var result = await TryHttpOperation.ExecuteAsync(() => _repository.GetUserAsync(id));

if (result.IsSuccess)
{
    Console.WriteLine(result.Value.Name);
}
else if (result.Code == HttpStatusCode.RequestTimeout)
{
    Console.WriteLine("The request timed out.");
}

Manual result β€” use when you need control over the success status code:

var result = await TryHttpOperation.ExecuteAsync(() => _apiClient.GetAsync<User>("users/1"));
Exception Mapping

Applies to all TryHttpOperation.ExecuteAsync overloads:

Exception Status Code
TaskCanceledException (timeout) 408 Request Timeout
HttpRequestException (with embedded code) Embedded HttpStatusCode
HttpRequestException (no embedded code) 503 Service Unavailable
Any other Exception 500 Internal Server Error
Custom Error Messages (exceptionMapper)

All TryHttpOperation.ExecuteAsync overloads accept the same optional Func<Exception, string>? exceptionMapper parameter. It controls only the error message β€” the HTTP status code mapping above is unaffected:

var result = await TryHttpOperation.ExecuteAsync(
    () => _apiClient.GetAsync<User>("users/1"),
    ex => "Upstream service is unavailable. Please try again later.");

βš–οΈ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ‘€ Author

FrΓ©dΓ©ric Goetinck-Moret

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.  net10.0 is compatible.  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.

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-beta.3 84 5/25/2026