CustomResultError 1.1.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package CustomResultError --version 1.1.1
NuGet\Install-Package CustomResultError -Version 1.1.1
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="CustomResultError" Version="1.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CustomResultError --version 1.1.1
#r "nuget: CustomResultError, 1.1.1"
#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 CustomResultError as a Cake Addin
#addin nuget:?package=CustomResultError&version=1.1.1

// Install CustomResultError as a Cake Tool
#tool nuget:?package=CustomResultError&version=1.1.1

CustomResultError

The modern Result Error types adjusted to modern AOT needs.

Combine the power of Results and Errors using a "discriminated union" approach.

How to install

Via tha Package Manager:

Install-Package CustomResultError

Via the .NET CLI

dotnet add package CustomResultError

Error

Generic Error<CodeType> inherit from the Error base class. The Error class is an immutable object which contains the properties Message (string) and Details (string[]). For the generic error, the CodeType is the type of an additional Code property. The errors are considered equal if their corresponding Code properties are equal.

Error<int> e4 = new("mpe", code: 125);
Error<int> e5 = new("mpou", code: 125);
Console.WriteLine(e5); //will print the Message, i.e. "mpe"
Console.WriteLine(e4 == e5); //will print "True" because their codes are the same.

Error<string> e6 = new("mpa", "CODE1");
Error<string> e7 = new("mpampou", "CODE1"); //will return True because their codes are the same.

In the AOT world you cannot use the JsonSerializer methods, because they use Reflection, which is not allowed. For this reason, the Error objects have a ToJsonString method which simplifies output especially in the case of Web endpoints. The ToString() overriden method returns only the Message. Below are some examples that show how to export a full JSON string:


//the simplest case 
Error<int> e4 = new("mpe", 125);
Console.WriteLine(e4.ToJsonString());

//we can add sub-errors/details by adding more arguments in the constructor (or by passing a string array)
Error<int> e4a = new("mpe", 125,"suberror1","suberror2");
Console.WriteLine(e4a.ToJsonString());

The first case will print:

{
    "code" : 125,
    "message" : "mpe"
}

The second case will print:

{
    "code" : 125,
    "message" : "mpe",
    "details" : ["suberror1", "suberror2"]
}

ExceptionError

ExceptionError is a special Error object that inherit from Error<Exception>. For convenience purposes it adds a domain (string) before the name of the exception, in order to generate a domain-specific exception code (the domain is optional). The Message property gets its value from the Exception.Message property and the Details array is populated from internal exception if they exist. The Code property itself contains the Exception object, so any stack information is preserved. For example:

Exception e = new InvalidOperationException("bamboo", new OperationCanceledException("mpeeee"));
ExceptionError error = new(e,domain:"MAIN");
Console.WriteLine(error.ToJsonString());

will print the following:

{
    "code" : "MAIN.InvalidOperationException",
    "message" : "bamboo",
    "details" : ["mpeeee"]
}

Result

The Result class is designed in a way to behave like a union. A (very) simple example below, shows the implicit conversion from the result type, or the error to a Result instance:

Result<int, Error<string>> result;

int a=5,b=6;
if (a < b)
    result = Result.Ok(a+b);
else
    result = Result.Fail(new Error<string>("This was a bad calc.","App.CalcError"));

//or (due to implicit conversions the code below is equivalent to the code above)
if (a < b)
    result = a+b;
else
    result = new Error<string>("This was a bad calc.","App.CalcError");

The Result instance contains the Value and Error properties. A continuation of the previous result is the following:

IResult res;
if (result.IsSuccess)
    res = Results.Ok(result.Value);
else
    res = Results.BadRequest(result.Error);

There are 2 more compact ways to write the same statemens above, using the Match function:

res = result.Match<IResult>( v => Results.Ok(v), e => Results.BadRequest(e));

//or
res = result.Match<IResult>(Results.Ok, Results.BadRequest);

//or  (the IResult return type is implied from the return type of the functions)
res = result.Match(Results.Ok, Results.BadRequest);

The Match function takes 2 functions (Func) are arguments. The first is a function that gets the Value and returns an IResult and the second functions gets the Error and returns a different IResult.

The Switch function is similar to the Match function but takes as arguments functions that do not return any value aka Action. In the example below, the first Action happens on success, while the second Action happens on failure.

result.Switch(v => Console.WriteLine($"YES! The value is {v}"),
    e=>Console.WriteLine($"NO! The error is {e}"));

Error parsing and AOT

But wait, what AOT compiling has to do with all these? The problem with AOT, is that reflection is not supported. Methods that support deserialization such as AsJsonAsync, will not work. This Error class supports parsing without the use of Reflection and therefore IS AOT compatible.

See the two examples below. The jsonString might come from the text response content of an HTTP call:

Error<int> e1 = new("messsad", 200, "sub1", "sub2");
string jsonString = e1.ToJsonString();
var e1_c = Error<int>.Parse(jsonString); //parsing does not use reflection here
Console.WriteLine(e1==e1_c);//will print True

Error<string> e2 = new(message:"messsad",code: "DSAD.asd", "sub1", "sub2");
jsonString = e2.ToJsonString();

var e2_c = Error<string>.Parse(jsonString); //parsing does not use reflection here
Console.WriteLine(e2 == e2_c); //will print True

MORE EXAMPLES TO FOLLOW

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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.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.2.12 79 5/4/2024
1.2.11 60 5/3/2024
1.2.10 65 5/3/2024
1.2.9 57 5/3/2024
1.2.8 47 5/3/2024
1.2.7 36 5/3/2024
1.2.6 43 5/3/2024
1.2.5 37 5/3/2024
1.2.4 37 5/3/2024
1.2.2 39 5/3/2024
1.2.1 40 5/3/2024
1.2.0 39 5/3/2024
1.1.15 98 3/28/2024
1.1.14 92 3/28/2024
1.1.13 90 3/27/2024
1.1.12 82 3/26/2024
1.1.11 92 3/24/2024
1.1.10 90 3/10/2024
1.1.9 96 3/10/2024
1.1.8 89 3/8/2024
1.1.7 83 3/8/2024
1.1.6 88 3/8/2024
1.1.5 72 3/5/2024
1.1.4 94 3/4/2024
1.1.3 76 3/3/2024
1.1.2 84 3/3/2024
1.1.1 103 3/3/2024
1.1.0 83 3/2/2024
1.0.5 100 3/1/2024
1.0.4 120 3/1/2024
1.0.2 84 3/1/2024
1.0.1 85 3/1/2024