Hart.ErrorHandlers
3.1.0
See the version list below for details.
dotnet add package Hart.ErrorHandlers --version 3.1.0
NuGet\Install-Package Hart.ErrorHandlers -Version 3.1.0
<PackageReference Include="Hart.ErrorHandlers" Version="3.1.0" />
paket add Hart.ErrorHandlers --version 3.1.0
#r "nuget: Hart.ErrorHandlers, 3.1.0"
// Install Hart.ErrorHandlers as a Cake Addin #addin nuget:?package=Hart.ErrorHandlers&version=3.1.0 // Install Hart.ErrorHandlers as a Cake Tool #tool nuget:?package=Hart.ErrorHandlers&version=3.1.0
Hart.ErrorHandlers
Purpose
This project purpose is to provide helpers for error handling in .NET Standard. Basically anything involving wrapping exceptions, method calls, retrying, etc.
Language
This is a C# .Net Standard 2.0 library.
Where to get it
You can download the latest version from nuget.org or also from the nuget package manager in VS by searching for Hart.ErrorHandlers
.
Safe Result returns
IResult is the interface that any type built to wrap function call results should implement. It's main purpose is to allow the needed covariance to return multiple types from the same function but "packed" under the same umbrella. IT also provides some methods to check if the call is Ok or if it returned any value.
Usage example:
var calculator = new Calculator();
// Divide by zero exception.
IResult<double> result = calculator.DoDivision(10, 0);
// The user has to check the type before accessing to the value.
if (result is Error) {
var exception = (result as Error).ExceptionValue;
Console.WriteLine(exception);
}
// Or...
if (result is Success && result is Success<double>) {
double divResult = (result as Success<double>).Value;
Console.WriteLine(divResult);
}
Implementation in method:
// Doing division could throw a divide by zero exception.
public IResult<double> DoDivision(int x, int y)
{
IResult<double> result;
try
{
result = new Success<double>(x / y);
}
catch(DivideByZeroException ex)
{
result = new Error<double>(ex);
}
catch (Exception ex)
{
result = new Error<double>(ex);
}
return result;
}
There are examples of how to use the library on the Hart.ErrorHandlersTests project.
Retrying
In the namespace Hart.ErrorHandlers.Retry you will find and static class Retrier
used to configure and retry functions or actions in a safe way.
There are options to configure the number of retries, the ms wait between retries
or even if the retrier will keep retrying until successful.
In it's simplest way it looks like this:
var res = Retrier.Init() // Create the default retry config
.Invoke(() => 2 + 2); // Pass the function to execute
int four = res.Result;
More Examples:
/// Call a function that will fail 5 times and return a default value.
var res = Retrier.Init()
.WithMsWaitOf(100)
.WithNumberOfRetries(5)
.Invoke(() => 2 / zero)
.WithFallBackValue(33);
// Calling and action.
var res = Retrier.Init()
.Invoke(() => Trace.WriteLine("action"))
.WithFallBack(() => Trace.WriteLine("fallback"));;
The default configuration is 3 retries with 0 ms wait between retries.
Of course it also supports async methods. But it's important to remember that you should use the .InvokeAsync method instead of the regular Invoke. It works for Funcs and Actions.
// You can use the .WaitForValue to keep chaining methods.
// (this way the method that contains this Retry doesn't need to be marked async)
public int GetValue() {
var result = Retrier.Init()
.WithNumberOfRetries(1)
.InvokeAsync(async () => await yourAsyncFunction())
.WaitForValue();
}
// Or if it's the last call, just use the regular await syntax.
public async int GetValueAsync() {
// In this case needs the async and await keywords.
var result = await Retrier.Init()
.WithNumberOfRetries(1)
.InvokeAsync(async () => await yourAsyncFunction());
}
// You also can use fallback async calls.
var result = Retrier.Init()
.WithNumberOfRetries(5)
.InvokeAsync(async () => await yourAsyncFunction())
.WaitForValue()
.WithFallbackAsync(async () => await yourAsyncFallbackFunction())
.WaitForValue();
This class will try to handle any kind of errors that happen inside and return the result if successful, a collection with the possible exceptions thrown and also information about the fallback execution. Also contains the number of executions.
You can find more about what it returns on the class RetryResult<T>
or RetryResult
.
IMPORTANT: Since it doesn't throw exceptions you should check that the operation was successful before using the returned value. For example, a function that returns
int
that fails will return 0 as a Result, but also a list of exceptions.
Example:
var res = Retrier.Init()
.Invoke(() => 2 + 2);
// Check if the function was successful.
if (res.Successful)
{
Console.WriteLine(res.Result); // 4
} else {
Console.WriteLine(res.RetryInfo
.Exceptions
.FirstOrDefault()
.Message);
}
// Number of executions of the function. (1)
Console.WriteLine(res.RetryInfo.Executions);
If too many failed retries are done the Exceptions collection could grow so much as to throw an OutOfMemoryException. Please, use it with caution. In future versions it will be possible to opt-out from doing exception logging and only store the last one or none.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.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.