Comments (3)
I am also looking at a similar feature like this. On top of that, I am also trying to have Then
mixing to aggregate multiple results from previous steps. Maybe the said proposal can also cover the following scenario at the same time, where I frequently will create multiple ErrorOr
values that have nothing to do with each other, but will be used in a common function at the end.
var userQuery = await sender.Send(new UserQuery(request.UserExternalId), cancellationToken); --> This method returns ErrorOr value
if (userQuery.IsError)
{
return userQuery.Errors;
}
return await sender.Send(new TransactionSingleQuery(request.UserExternalId, request.TransactionGroupId), cancellationToken) --> This method returns ErrorOr value
.ThenAsync(async x =>
{
var update = x.TransactionGroup.Update(
request.TransactionTime,
request.Description,
request.Amount,
userQuery.Value.User, --> This is the part that I hope to be able to chain together in Then mixing from userQuery
timeProvider.GetUtcNow(),
from,
to);
await repository.UpdateTransactionGroup(update);
return new TransactionUpdateResult(update.Id);
})
.Else(x => x);
from error-or.
I am also looking at a similar feature like this. On top of that, I am also trying to have
Then
mixing to aggregate multiple results from previous steps. Maybe the said proposal can also cover the following scenario at the same time, where I frequently will create multipleErrorOr
values that have nothing to do with each other, but will be used in a common function at the end.var userQuery = await sender.Send(new UserQuery(request.UserExternalId), cancellationToken); --> This method returns ErrorOr value if (userQuery.IsError) { return userQuery.Errors; } return await sender.Send(new TransactionSingleQuery(request.UserExternalId, request.TransactionGroupId), cancellationToken) --> This method returns ErrorOr value .ThenAsync(async x => { var update = x.TransactionGroup.Update( request.TransactionTime, request.Description, request.Amount, userQuery.Value.User, --> This is the part that I hope to be able to chain together in Then mixing from userQuery timeProvider.GetUtcNow(), from, to); await repository.UpdateTransactionGroup(update); return new TransactionUpdateResult(update.Id); }) .Else(x => x);
You can achive this behavior by forwarding the result using Tuples
.
Created an example for you
using ErrorOr;
ErrorOr<TransactionGroup> Handle(ISender sender, int externalUserId, int transactionGroupId) =>
new UserQuery(externalUserId)
.ToErrorOr()
.Then(userQuery => sender.Send(userQuery))
.Then(user => (user, new TransactionSingleQuery(externalUserId, transactionGroupId)))
.Then(tuple => (tuple.Item1, sender.Send(tuple.Item2)))
.Then(
(tuple) =>
{
User user = tuple.Item1;
TransactionGroup transactionGroup = tuple.Item2;
// do work with these
return transactionGroup;
}
);
record User(int Id, string Name);
record UserQuery(int ExternalUserId);
record TransactionSingleQuery(int ExternalUserId, int TransactionGroupId);
record TransactionGroup(int Id, DateTime TransactionDateTime);
interface ISender
{
User Send(UserQuery query);
TransactionGroup Send(TransactionSingleQuery query);
}
from error-or.
What dou you think about the following propose?
Before:
public static ErrorOr<SomeResult> Create(string value1, string value2) { ErrorOr<Value1> value1OrError = Value1.Create(value1); ErrorOr<Value2> value2OrError = Value2.Create(value2); var errors = new List<Error>(); errors.AddRange(value1OrError.Errors); errors.AddRange(value2OrError.Errors); if(errors.Count > 0) { return errors; } return new SomeResult(value1OrError.Value, value2OrError.Value); }After (Option 1 - Separate class)
public static ErrorOr<SomeResult> Create(string value1, string value2) { ErrorOr<Value1> value1OrError = Value1.Create(value1); ErrorOr<Value2> value2OrError = Value2.Create(value2); return ErrorCollector .Collect(value1OrError , value2OrError ) .Then(x => new SomeResult(value1OrError.Value, value2OrError.Value)); }After (Option 2 - ErrorOrFactory)
public static ErrorOr<SomeResult> Create(string value1, string value2) { ErrorOr<Value1> value1OrError = Value1.Create(value1); ErrorOr<Value2> value2OrError = Value2.Create(value2); return ErrorOrFactory .CollectErrors(value1OrError , value2OrError ) .Then(() => new SomeResult(value1OrError.Value, value2OrError.Value)); }Implementation propose:
public static ErrorOr<Result> CollectErrors<Result>(params IErrorOr[] errorsToCombine) { if (errorsToCombine.Any(x => x.IsError)) { return errorsToCombine.SelectMany(x => x.Errors); } return Result.Success; }Of course, improvements are required to handle cases like null values.
To achieve the similar behavior. I created a custom extension like this.
public static class Errors
{
public static List<Error> Combine(params IErrorOr[] errorOrs) =>
errorOrs
.Where(x => x.IsError)
.Where(x => x.Errors is not null)
.SelectMany(x => x.Errors!)
.ToList();
}
Maybe a static method on Error
or ErrorOrFactory
will do the trick.
You can find an example usage of the extension method I created below.
ErrorOr<Success> HandleUpdateUser()
{
User user = GetUser();
if (
Errors.Combine(user.SetFirstName(string.Empty), user.SetLastName(string.Empty))
is var errors
and { Count: not 0 }
)
{
return errors;
}
return Result.Success;
}
class User
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
public ErrorOr<Updated> SetFirstName(string firstName)
{
if (string.IsNullOrWhiteSpace(firstName))
{
return Error.Validation(description: "First name is required");
}
return Result.Updated;
}
public ErrorOr<Updated> SetLastName(string lastName)
{
if (string.IsNullOrWhiteSpace(lastName))
{
return Error.Validation(description: "Last name is required");
}
return Result.Updated;
}
}
from error-or.
Related Issues (20)
- [Request] Please sign the NuGet with a strong name HOT 2
- [Bug] Error equality not working as intended HOT 4
- SUGGESTION: Add a changelog for each version released HOT 1
- erroror is missing NuGet package README file HOT 2
- Return ErrorOr<?> HOT 2
- [Request] Add overload without capturing errors or values in functional methods
- [Bug/Enhancement] ErrorOr should not "invent" a result value in case error, it should force caller to handle error instead HOT 6
- [Question] ASP.net Is there a response type i can deserialize to? HOT 2
- [Enhancement] Add FailIf from Task<T>
- [Question] Error Result from MediatR pipeline behaviour HOT 2
- [Enhancement] Avoid duplicated runtime memory by moving NoFirstError and NoErrors into non-generic type HOT 1
- [Question]: Should it be possible to instantiate ErrorOr<TValue> with an empty error list? HOT 8
- MatchAsync giving an error when IActionResult is returned from Api Contoller. HOT 3
- Potential misuse HOT 5
- How this project is related to CSharpFunctionalExtensions? HOT 4
- FailIf example does not work HOT 5
- Should Error instances have a dedicated Exception property?
- Breaking Change in v2.1 / Serializing to json HOT 2
- Enhancement - Add an easy way to throw for null, empty or whitespace
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from error-or.