From df3bde2fcf6bb53ef523251aeb6e602717eafc6e Mon Sep 17 00:00:00 2001 From: adimiko Date: Fri, 14 Mar 2025 21:08:35 +0100 Subject: [PATCH 1/2] Added new command result errors --- samples/EasyWay.Samples/Program.cs | 7 +++ .../Internals/WebApiResultMapper.cs | 7 +++ source/EasyWay/CommandResult.cs | 53 ++++++++++++++++++- .../Commands/Commands/CommandExecutor.cs | 14 ++++- .../CommandsWithResult/CommandErrorEnum.cs | 2 +- .../CommandWithOperationResultExecutor.cs | 14 ++++- 6 files changed, 90 insertions(+), 7 deletions(-) diff --git a/samples/EasyWay.Samples/Program.cs b/samples/EasyWay.Samples/Program.cs index 659a42f..6f16c37 100644 --- a/samples/EasyWay.Samples/Program.cs +++ b/samples/EasyWay.Samples/Program.cs @@ -39,6 +39,13 @@ await kernel return mapper.Map(x); }); +app.MapPost("/commandWithError", async ([FromBody] ErrorCommand command, IModuleExecutor executor, IWebApiResultMapper mapper) => +{ + var x = await executor.Command(command); + + return mapper.Map(x); +}); + app.MapPost("/command", async ([FromBody] SampleCommand command, IModuleExecutor executor, IWebApiResultMapper mapper) => { var x = await executor.Command(command); diff --git a/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs b/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs index 8428117..0fff876 100644 --- a/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs +++ b/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs @@ -1,4 +1,5 @@ using EasyWay.Internals.Commands.CommandsWithResult; +using EasyWay.Internals.Exceptions; using EasyWay.Internals.Queries.Results; using Microsoft.AspNetCore.Http; @@ -12,6 +13,9 @@ public IResult Map(CommandResult commandResult) { CommandErrorEnum.None => Results.Ok(), CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), + CommandErrorEnum.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.BrokenBusinessRuleException)), + CommandErrorEnum.NotFound => Results.StatusCode(404), + CommandErrorEnum.Forbidden => Results.StatusCode(403), _ => Results.StatusCode(500), }; } @@ -22,6 +26,9 @@ public IResult Map(CommandResult commandResu { CommandErrorEnum.None => Results.Ok(commandResult.OperationResult), CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), + CommandErrorEnum.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.BrokenBusinessRuleException)), + CommandErrorEnum.NotFound => Results.StatusCode(404), + CommandErrorEnum.Forbidden => Results.StatusCode(403), _ => Results.StatusCode(500), }; } diff --git a/source/EasyWay/CommandResult.cs b/source/EasyWay/CommandResult.cs index 12bacd7..259fa4a 100644 --- a/source/EasyWay/CommandResult.cs +++ b/source/EasyWay/CommandResult.cs @@ -1,4 +1,5 @@ -using EasyWay.Internals.Commands.CommandsWithResult; +using EasyWay.Internals.BusinessRules; +using EasyWay.Internals.Commands.CommandsWithResult; namespace EasyWay { @@ -8,32 +9,58 @@ public sealed class CommandResult internal IDictionary ValidationErrors; + internal BrokenBusinessRuleException? BrokenBusinessRuleException; + private CommandResult() { Error = CommandErrorEnum.None; ValidationErrors = new Dictionary(); + BrokenBusinessRuleException = null; + } + + private CommandResult(CommandErrorEnum error) + { + Error = error; + ValidationErrors = new Dictionary(); + BrokenBusinessRuleException = null; } private CommandResult(IDictionary validationErrors) { Error = CommandErrorEnum.Validation; ValidationErrors = validationErrors; + BrokenBusinessRuleException = null; + } + + private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException) + { + Error = CommandErrorEnum.BrokenBusinessRule; + ValidationErrors = new Dictionary(); + BrokenBusinessRuleException = brokenBusinessRuleException; } + internal static CommandResult BrokenBusinessRule(BrokenBusinessRuleException brokenBusinessRuleException) => new CommandResult(brokenBusinessRuleException); + internal static CommandResult Validation(IDictionary validationErrors) => new CommandResult(validationErrors); public static CommandResult Ok => new CommandResult(); + + public static CommandResult NotFound => new CommandResult(CommandErrorEnum.NotFound); + + public static CommandResult Forbidden => new CommandResult(CommandErrorEnum.Forbidden); } public sealed class CommandResult where TOperationResult : OperationResult { - internal TOperationResult OperationResult { get; } + internal TOperationResult? OperationResult { get; } internal CommandErrorEnum Error { get; } internal IDictionary ValidationErrors; + internal BrokenBusinessRuleException? BrokenBusinessRuleException; + private CommandResult(TOperationResult operationResult) { OperationResult = operationResult; @@ -43,12 +70,34 @@ private CommandResult(TOperationResult operationResult) private CommandResult(IDictionary validationErrors) { + OperationResult = null; Error = CommandErrorEnum.Validation; ValidationErrors = validationErrors; } + private CommandResult(CommandErrorEnum error) + { + OperationResult = null; + Error = error; + ValidationErrors = new Dictionary(); + } + + private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException) + { + OperationResult = null; + Error = CommandErrorEnum.BrokenBusinessRule; + ValidationErrors = new Dictionary(); + BrokenBusinessRuleException = brokenBusinessRuleException; + } + internal static CommandResult Validation(IDictionary validationErrors) => new CommandResult(validationErrors); + internal static CommandResult BrokenBusinessRule(BrokenBusinessRuleException brokenBusinessRuleException) => new CommandResult(brokenBusinessRuleException); + public static CommandResult Ok(TOperationResult operationResult) => new CommandResult(operationResult); + + public static CommandResult NotFound => new CommandResult(CommandErrorEnum.NotFound); + + public static CommandResult Forbidden => new CommandResult(CommandErrorEnum.Forbidden); } } diff --git a/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs b/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs index 0356ba2..280a38f 100644 --- a/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs +++ b/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs @@ -1,4 +1,5 @@ -using EasyWay.Internals.Validation; +using EasyWay.Internals.BusinessRules; +using EasyWay.Internals.Validation; using Microsoft.Extensions.DependencyInjection; namespace EasyWay.Internals.Commands.Commands @@ -39,9 +40,18 @@ public async Task Execute(TCommand command, Ca } } - var commandResult = await _serviceProvider + CommandResult commandResult; + + try + { + commandResult = await _serviceProvider .GetRequiredService>() .Handle(command); + } + catch (BrokenBusinessRuleException brokenBusinessRuleException) + { + return CommandResult.BrokenBusinessRule(brokenBusinessRuleException); + } await _unitOfWork.Commit(); diff --git a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs index 4a013f0..6ab58db 100644 --- a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs +++ b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs @@ -4,7 +4,7 @@ internal enum CommandErrorEnum { None, Validation, - BusinessRule, + BrokenBusinessRule, NotFound, Forbidden, } diff --git a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs index 9ad467e..16d6b58 100644 --- a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs +++ b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs @@ -1,4 +1,5 @@ -using EasyWay.Internals.Validation; +using EasyWay.Internals.BusinessRules; +using EasyWay.Internals.Validation; using Microsoft.Extensions.DependencyInjection; namespace EasyWay.Internals.Commands.CommandsWithResult @@ -42,7 +43,16 @@ public async Task> Command>(); - var commandResult = await commandHandler.Handle(command); + CommandResult commandResult; + + try + { + commandResult = await commandHandler.Handle(command); + } + catch (BrokenBusinessRuleException brokenBusinessRuleException) + { + return CommandResult.BrokenBusinessRule(brokenBusinessRuleException); + } await _unitOfWork.Commit(); From 6c19eed8fe24d5325813161749adb18e2799f239 Mon Sep 17 00:00:00 2001 From: adimiko Date: Fri, 14 Mar 2025 21:10:44 +0100 Subject: [PATCH 2/2] Refactored code --- source/EasyWay/CommandResult.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/EasyWay/CommandResult.cs b/source/EasyWay/CommandResult.cs index 259fa4a..b7ce73f 100644 --- a/source/EasyWay/CommandResult.cs +++ b/source/EasyWay/CommandResult.cs @@ -66,6 +66,7 @@ private CommandResult(TOperationResult operationResult) OperationResult = operationResult; Error = CommandErrorEnum.None; ValidationErrors = new Dictionary(); + BrokenBusinessRuleException = null; } private CommandResult(IDictionary validationErrors) @@ -73,6 +74,7 @@ private CommandResult(IDictionary validationErrors) OperationResult = null; Error = CommandErrorEnum.Validation; ValidationErrors = validationErrors; + BrokenBusinessRuleException = null; } private CommandResult(CommandErrorEnum error) @@ -80,6 +82,7 @@ private CommandResult(CommandErrorEnum error) OperationResult = null; Error = error; ValidationErrors = new Dictionary(); + BrokenBusinessRuleException = null; } private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException)