Skip to content

Commit

Permalink
Merge pull request #142 from mtyski/feature/LazyErrorEvaluation
Browse files Browse the repository at this point in the history
Lazy error evaluation
  • Loading branch information
altmann authored Aug 4, 2022
2 parents 337e46e + 27151a6 commit cc87231
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,20 @@ With the methods ```FailIf()``` and ```OkIf()``` you can also write in a more re
var result = Result.FailIf(string.IsNullOrEmpty(firstName), "First Name is empty");
```

If an error instance should be lazily initialized, overloads accepting ```Func<string>``` or ```Func<IError>``` can be used to that effect:

```csharp
var list = Enumerable.Range(1, 9).ToList();

var result = Result.FailIf(
list.Any(IsDivisibleByTen),
() => new Error()$"Item {list.First(IsDivisibleByTen)}" should not be on the list));

bool IsDivisibleByTen(int i) => i % 10 == 0;

// rest of the code
```

### Try

In some scenarios you want to execute an action. If this action throws an exception then the exception should be catched and transformed to a result object.
Expand Down
89 changes: 89 additions & 0 deletions src/FluentResults.Test/ResultWithoutValueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,50 @@ public void FailIf_FailedConditionIsFalseAndWithObjectErrorMessage_CreateFailedR
result.IsFailed.Should().BeFalse();
}

[Fact]
public void FailIf_FailedConditionIsFalseAndWithObjectErrorFactory_CreateSuccessResult()
{
var result = Result.FailIf(false, LazyError);

result.IsFailed.Should().BeFalse();

Error LazyError()
{
throw new Exception("This should not be thrown!");
}
}

[Fact]
public void FailIf_FailedConditionIsFalseAndWithStringErrorMessageFactory_CreateSuccessResult()
{
var result = Result.FailIf(false, LazyError);

result.IsFailed.Should().BeFalse();

string LazyError()
{
throw new Exception("This should not be thrown!");
}
}

[Fact]
public void FailIf_FailedConditionIsTrueAndWithObjectErrorFactory_CreateFailedResult()
{
var result = Result.FailIf(true, () => "Error message");

result.IsFailed.Should().BeTrue();
result.Errors.Single().Message.Should().Be("Error message");
}

[Fact]
public void FailIf_FailedConditionIsTrueAndWithStringErrorMessageFactory_CreateFailedResult()
{
var result = Result.FailIf(true, () => new Error("Error message"));

result.IsFailed.Should().BeTrue();
result.Errors.Single().Message.Should().Be("Error message");
}

[Fact]
public void OkIf_SuccessConditionIsTrueAndWithStringErrorMessage_CreateFailedResult()
{
Expand All @@ -246,6 +290,32 @@ public void OkIf_SuccessConditionIsTrueAndWithObjectErrorMessage_CreateFailedRes
result.IsSuccess.Should().BeTrue();
}

[Fact]
public void OkIf_SuccessConditionIsTrueAndWithStringErrorMessageFactory_CreateSuccessResult()
{
var result = Result.OkIf(true, LazyError);

result.IsSuccess.Should().BeTrue();

string LazyError()
{
throw new Exception("This should not be thrown!");
}
}

[Fact]
public void OkIf_SuccessConditionIsTrueAnWithObjectErrorMessageFactory_CreateSuccessResult()
{
var result = Result.OkIf(true, LazyError);

result.IsSuccess.Should().BeTrue();

Error LazyError()
{
throw new Exception("This should not be thrown!");
}
}

[Fact]
public void OkIf_SuccessConditionIsFalseAndWithStringErrorMessage_CreateFailedResult()
{
Expand All @@ -266,6 +336,25 @@ public void OkIf_SuccessConditionIsFalseAndWithObjectErrorMessage_CreateFailedRe
result.Errors.Single().Message.Should().Be("Error message");
}

[Fact]
public void OkIf_SuccessConditionIsFalseAndWithStringErrorMessageFactory_CreateFailedResult()
{
const string errorMessage = "Error message";
var result = Result.OkIf(false, () => errorMessage);

result.IsFailed.Should().BeTrue();
result.Errors.Single().Message.Should().Be(errorMessage);
}

[Fact]
public void OkIf_SuccessConditionIsFalseAndWithObjectErrorMessageFactory_CreateFailedResult()
{
const string errorMessage = "Error message";
var result = Result.OkIf(false, () => new Error(errorMessage));

result.IsFailed.Should().BeTrue();
result.Errors.Single().Message.Should().Be(errorMessage);
}

[Fact]
public void Try_execute_successfully_action_return_success_result()
Expand Down
44 changes: 44 additions & 0 deletions src/FluentResults/Factories/Results.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ public static Result OkIf(bool isSuccess, string error)
return isSuccess ? Ok() : Fail(error);
}

/// <summary>
/// Create a success/failed result depending on the parameter isSuccess
/// </summary>
/// <remarks>
/// Error is lazily evaluated.
/// </remarks>
public static Result OkIf(bool isSuccess, Func<IError> errorFactory)
{
return isSuccess ? Ok() : Fail(errorFactory.Invoke());
}

/// <summary>
/// Create a success/failed result depending on the parameter isSuccess
/// </summary>
/// <remarks>
/// Error is lazily evaluated.
/// </remarks>
public static Result OkIf(bool isSuccess, Func<string> errorMessageFactory)
{
return isSuccess ? Ok() : Fail(errorMessageFactory.Invoke());
}

/// <summary>
/// Create a success/failed result depending on the parameter isFailure
/// </summary>
Expand All @@ -184,6 +206,28 @@ public static Result FailIf(bool isFailure, string error)
return isFailure ? Fail(error) : Ok();
}

/// <summary>
/// Create a success/failed result depending on the parameter isFailure
/// </summary>
/// <remarks>
/// Error is lazily evaluated.
/// </remarks>
public static Result FailIf(bool isFailure, Func<IError> errorFactory)
{
return isFailure ? Fail(errorFactory.Invoke()) : Ok();
}

/// <summary>
/// Create a success/failed result depending on the parameter isFailure
/// </summary>
/// <remarks>
/// Error is lazily evaluated.
/// </remarks>
public static Result FailIf(bool isFailure, Func<string> errorMessageFactory)
{
return isFailure ? Fail(errorMessageFactory.Invoke()) : Ok();
}

/// <summary>
/// Executes the action. If an exception is thrown within the action then this exception is transformed via the catchHandler to an Error object
/// </summary>
Expand Down

0 comments on commit cc87231

Please sign in to comment.