Skip to content

Commit

Permalink
Release 1.8.0
Browse files Browse the repository at this point in the history
## [1.8.0] - Sep, 2024
- Added `WithMessage` to the `Error` class to allow the error message to be changed. It will allow for more flexibility when
  handling errors;
  • Loading branch information
brenordv authored Sep 8, 2024
2 parents 57e456a + 67b7363 commit 15ea0e1
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 10 deletions.
5 changes: 4 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Changelog

## [1.8.0] - Sep, 2024
- Added `WithMessage` to the `Error` class to allow the error message to be changed. It will allow for more flexibility when
handling errors;

## [1.7.0] - Sep, 2024
- Added `ChainOnSuccess` and `ChainOnSuccessAsync` extension methods to help reduce boilerplate;


## [1.6.0] - Sep, 2024
- Added `TapOnSuccess` and `TapOnSuccessAsync` extension methods to help reduce boilerplate;

Expand Down
4 changes: 4 additions & 0 deletions operation-result.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ It's a somewhat functional approach to handling operation results, not fully adh
paradigm but providing some of its benefits.

## Methods
### Result<T>
- `Tap`: Taps into the result instance and executes the appropriate action based on whether it is a success or a failure.
- `TapAsync`: Taps into the result instance and executes the appropriate asynchronous action based on whether it is a success or a failure.
- `Process`: Processes the result and returns a value based on whether it is a success or a failure.
Expand All @@ -16,6 +17,9 @@ paradigm but providing some of its benefits.
- `[Result<bool> Extension] ChainOnSuccess`: Chains the provided function if the result is a success and the payload is true.
- `[Result<bool> Extension] ChainOnSuccessAsync`: Chains the provided asynchronous function if the result is a success and the payload is true.

### Error
- `WithExcception`: Creates a new error instance with the provided exception. This allows you to re-use an error object, by adding a new piece of information to it (the exception)

## Example Usage
```csharp
using Raccoon.Ninja.Tools.OperationResult;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public class ErrorTests
{
private const string InvalidCtorArgsMessage = "Both error message and exception are null or empty.";

#region Constructor

[Fact]
public void Constructor_ShouldThrowException_WhenBothErrorMessageAndExceptionAreNullImplicitly()
{
Expand All @@ -19,12 +21,13 @@ public void Constructor_ShouldThrowException_WhenBothErrorMessageAndExceptionAre
act.Should().Throw<OperationResultException>()
.WithMessage("Default constructor is not allowed.");
}

[Theory]
[InlineData(null, null)]
[InlineData("", null)]
[InlineData(" ", null)]
public void Constructor_ShouldThrowException_WhenBothErrorMessageIsNullExplicitly(string errorMessage, Exception exception)
public void Constructor_ShouldThrowException_WhenBothErrorMessageIsNullExplicitly(string errorMessage,
Exception exception)
{
// Act
Action act = () => new Error(errorMessage, exception);
Expand All @@ -45,7 +48,7 @@ public void Constructor_ShouldThrowException_WhenErrorMessageIsNull(string error
// Assert
act.Should().Throw<OperationResultException>().WithMessage("Error message is null or empty.");
}

[Fact]
public void Constructor_ShouldSetErrorMessage_WhenOnlyErrorMessageIsProvided()
{
Expand Down Expand Up @@ -89,6 +92,75 @@ public void Constructor_ShouldSetErrorMessageAndException_WhenBothAreProvided()
error.Exception.Should().Be(exception);
}

#endregion

#region WithException

[Fact]
public void WithException_ShouldThrowException_WhenStrictAndExceptionAlreadyExists()
{
// Arrange
var initialException = new Exception("Initial exception");
var error = new Error("Initial error message", initialException);
var newException = new Exception("New exception");

// Act
Action act = () => error.WithException(newException, strict: true);

// Assert
act.Should().Throw<OperationResultException>()
.WithMessage("Error already has an exception.");
}

[Fact]
public void WithException_ShouldReplaceException_WhenNotStrictAndExceptionAlreadyExists()
{
// Arrange
var initialException = new Exception("Initial exception");
var error = new Error("Initial error message", initialException);
var newException = new Exception("New exception");

// Act
var newError = error.WithException(newException, strict: false);

// Assert
newError.Exception.Should().Be(newException);
newError.ErrorMessage.Should().Be("Initial error message");
}

[Fact]
public void WithException_ShouldSetException_WhenNoExceptionExists()
{
// Arrange
var error = new Error("Initial error message");
var newException = new Exception("New exception");

// Act
var newError = error.WithException(newException);

// Assert
newError.Exception.Should().Be(newException);
newError.ErrorMessage.Should().Be("Initial error message");
}

[Fact]
public void WithException_ShouldThrowException_WhenExceptionIsNull()
{
// Arrange
var error = new Error("Initial error message");

// Act
Action act = () => error.WithException(null);

// Assert
act.Should().Throw<OperationResultException>()
.WithMessage("Exception is null.");
}

#endregion

#region ToString

[Fact]
public void ToString_ShouldReturnErrorMessage_WhenErrorMessageIsSet()
{
Expand Down Expand Up @@ -116,5 +188,7 @@ public void ToString_ShouldReturnExceptionMessage_WhenErrorMessageIsNotSet()
// Assert
result.Should().Be(exception.Message);
}

#endregion
}
}
38 changes: 37 additions & 1 deletion src/Raccoon.Ninja.Tools/OperationResult/ResultError/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public Error(Exception exception)
Exception = exception ?? throw new OperationResultException("Exception is null.");
ErrorMessage = exception.Message;
}

public Error(string errorMessage, Exception exception)
{
if (exception is null && string.IsNullOrWhiteSpace(errorMessage))
Expand All @@ -46,6 +46,42 @@ public Error(string errorMessage, Exception exception)
ErrorMessage = errorMessage ?? exception.Message;
}

/// <summary>
/// Returns a new Error instance with the provided exception.
/// </summary>
/// <param name="exception">The exception to associate with the error.</param>
/// <param name="strict">
/// If true, throws an OperationResultException if the current Error instance already has an exception.
/// If false, allows the new exception to replace the existing one.
/// </param>
/// <returns>A new Error instance with the provided exception.</returns>
/// <exception cref="OperationResultException">Thrown if strict is true and the current Error instance already has an exception.</exception>
/// <example>
/// <code>
/// var initialError = new Error("Initial error message");
/// try
/// {
/// // Some code that throws an exception
/// throw new InvalidOperationException("An invalid operation occurred.");
/// }
/// catch (Exception ex)
/// {
/// var newError = initialError.WithException(ex);
/// Console.WriteLine(newError);
/// }
/// </code>
/// </example>
public Error WithException(Exception exception, bool strict = true)
{
if (strict && Exception is not null)
throw new OperationResultException("Error already has an exception.");

if (exception is null)
throw new OperationResultException("Exception is null.");

return new Error(ErrorMessage, exception);
}

public override string ToString()
{
return ErrorMessage ?? Exception.ToString();
Expand Down
10 changes: 5 additions & 5 deletions src/Raccoon.Ninja.Tools/Raccoon.Ninja.Tools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<Version>1.7.0</Version>
<Version>1.8.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Title>Raccoon Ninja Tools</Title>
<Description>A collection of helpers and utilities to help improve and speed up development.</Description>
Expand All @@ -14,12 +14,12 @@
<RepositoryUrl>https://github.com/brenordv/nuget-raccoon-tools</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>utils utility toolset chsarp-library guid5 uuid5 uuidv5 uuid guid functional c-sharp csharp dotnetcore discriminated-unions extensions datetime list string</PackageTags>
<PackageReleaseNotes>## [1.7.0] - Sep, 2024
- Added `ChainOnSuccess` and `ChainOnSuccessAsync` extension methods to help reduce boilerplate;</PackageReleaseNotes>
<PackageReleaseNotes>## [1.8.0] - Sep, 2024
- Added `WithMessage` to the `Error` class to allow the error message to be changed. It will allow for more flexibility when handling errors;</PackageReleaseNotes>
<Authors>Breno RdV</Authors>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<AssemblyVersion>1.7.0</AssemblyVersion>
<FileVersion>1.7.0</FileVersion>
<AssemblyVersion>1.8.0</AssemblyVersion>
<FileVersion>1.8.0</FileVersion>
<NeutralLanguage>en-US</NeutralLanguage>
</PropertyGroup>

Expand Down

0 comments on commit 15ea0e1

Please sign in to comment.