From c513005170db7a08d03435deffd87a4ac31b7e4d Mon Sep 17 00:00:00 2001 From: adimiko Date: Fri, 14 Mar 2025 22:29:57 +0100 Subject: [PATCH] Added new command results --- .../BrokenBusinessRuleExceptionResponse.cs | 2 +- .../Internals/WebApiResultMapper.cs | 16 +++-- source/EasyWay/CommandResult.cs | 66 +++++++++++++++---- .../Internals/Commands/CommandErrorEnum.cs | 14 ++++ .../Commands/Commands/CommandExecutor.cs | 16 ++++- .../CommandsWithResult/CommandErrorEnum.cs | 11 ---- .../CommandWithOperationResultExecutor.cs | 16 ++++- 7 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 source/EasyWay/Internals/Commands/CommandErrorEnum.cs delete mode 100644 source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs diff --git a/source/EasyWay.WebApi/Internals/Exceptions/BrokenBusinessRuleExceptionResponse.cs b/source/EasyWay.WebApi/Internals/Exceptions/BrokenBusinessRuleExceptionResponse.cs index b4930c5..807c46c 100644 --- a/source/EasyWay.WebApi/Internals/Exceptions/BrokenBusinessRuleExceptionResponse.cs +++ b/source/EasyWay.WebApi/Internals/Exceptions/BrokenBusinessRuleExceptionResponse.cs @@ -5,7 +5,7 @@ namespace EasyWay.Internals.Exceptions { internal sealed class BrokenBusinessRuleExceptionResponse : ExceptionResponse { - internal BrokenBusinessRuleExceptionResponse(BrokenBusinessRuleException ex) + internal BrokenBusinessRuleExceptionResponse(Exception ex) { Type = "BrokenBusinessRule"; Detail = ex.Message; diff --git a/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs b/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs index b31d14c..4b259fd 100644 --- a/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs +++ b/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs @@ -1,4 +1,4 @@ -using EasyWay.Internals.Commands.CommandsWithResult; +using EasyWay.Internals.Commands; using EasyWay.Internals.Exceptions; using EasyWay.Internals.Queries.Results; using Microsoft.AspNetCore.Http; @@ -13,9 +13,11 @@ public IResult Map(CommandResult commandResult) { CommandErrorEnum.None => Results.Ok(), CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), - CommandErrorEnum.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.BrokenBusinessRuleException)), + CommandErrorEnum.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.Exception)), + CommandErrorEnum.ConcurrencyConflict => Results.StatusCode(409), + CommandErrorEnum.OperationCanceled => Results.StatusCode(499), CommandErrorEnum.NotFound => Results.StatusCode(404), - CommandErrorEnum.Forbidden => Results.StatusCode(403), + CommandErrorEnum.Forbidden => Results.StatusCode(404), _ => Results.StatusCode(500), }; } @@ -26,9 +28,11 @@ 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.BrokenBusinessRule => Results.Conflict(new BrokenBusinessRuleExceptionResponse(commandResult.Exception)), + CommandErrorEnum.ConcurrencyConflict => Results.StatusCode(409), + CommandErrorEnum.OperationCanceled => Results.StatusCode(499), CommandErrorEnum.NotFound => Results.StatusCode(404), - CommandErrorEnum.Forbidden => Results.StatusCode(403), + CommandErrorEnum.Forbidden => Results.StatusCode(404), _ => Results.StatusCode(500), }; } @@ -40,7 +44,7 @@ public IResult Map(QueryResult queryResult) where TReadM QueryErrorEnum.None => Results.Ok(queryResult.ReadModel), QueryErrorEnum.Validation => Results.BadRequest(queryResult.ValidationErrors), QueryErrorEnum.NotFound => Results.StatusCode(404), - QueryErrorEnum.Forbidden => Results.StatusCode(403), + QueryErrorEnum.Forbidden => Results.StatusCode(404), _ => Results.StatusCode(500), }; } diff --git a/source/EasyWay/CommandResult.cs b/source/EasyWay/CommandResult.cs index b7ce73f..dac7b4d 100644 --- a/source/EasyWay/CommandResult.cs +++ b/source/EasyWay/CommandResult.cs @@ -1,5 +1,7 @@ -using EasyWay.Internals.BusinessRules; -using EasyWay.Internals.Commands.CommandsWithResult; +using EasyWay.Internals; +using EasyWay.Internals.BusinessRules; +using EasyWay.Internals.Commands; +using System.Data; namespace EasyWay { @@ -9,40 +11,60 @@ public sealed class CommandResult internal IDictionary ValidationErrors; - internal BrokenBusinessRuleException? BrokenBusinessRuleException; + internal Exception? Exception; private CommandResult() { Error = CommandErrorEnum.None; ValidationErrors = new Dictionary(); - BrokenBusinessRuleException = null; + Exception = null; } private CommandResult(CommandErrorEnum error) { Error = error; ValidationErrors = new Dictionary(); - BrokenBusinessRuleException = null; + Exception = null; } private CommandResult(IDictionary validationErrors) { Error = CommandErrorEnum.Validation; ValidationErrors = validationErrors; - BrokenBusinessRuleException = null; + Exception = null; } private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException) { Error = CommandErrorEnum.BrokenBusinessRule; ValidationErrors = new Dictionary(); - BrokenBusinessRuleException = brokenBusinessRuleException; + Exception = brokenBusinessRuleException; + } + + private CommandResult(ConcurrencyException concurrencyException) + { + Error = CommandErrorEnum.ConcurrencyConflict; + ValidationErrors = new Dictionary(); + Exception = concurrencyException; + } + + public CommandResult(Exception exception) + { + Error = CommandErrorEnum.UnknownException; + ValidationErrors = new Dictionary(); + Exception = exception; } internal static CommandResult BrokenBusinessRule(BrokenBusinessRuleException brokenBusinessRuleException) => new CommandResult(brokenBusinessRuleException); internal static CommandResult Validation(IDictionary validationErrors) => new CommandResult(validationErrors); + internal static CommandResult ConcurrencyConflict(ConcurrencyException concurrencyException) => new CommandResult(concurrencyException); + + internal static CommandResult OperationCanceled() => new CommandResult(CommandErrorEnum.OperationCanceled); + + internal static CommandResult UnknownException(Exception exception) => new CommandResult(exception); + public static CommandResult Ok => new CommandResult(); public static CommandResult NotFound => new CommandResult(CommandErrorEnum.NotFound); @@ -59,14 +81,14 @@ public sealed class CommandResult internal IDictionary ValidationErrors; - internal BrokenBusinessRuleException? BrokenBusinessRuleException; + internal Exception? Exception; private CommandResult(TOperationResult operationResult) { OperationResult = operationResult; Error = CommandErrorEnum.None; ValidationErrors = new Dictionary(); - BrokenBusinessRuleException = null; + Exception = null; } private CommandResult(IDictionary validationErrors) @@ -74,7 +96,7 @@ private CommandResult(IDictionary validationErrors) OperationResult = null; Error = CommandErrorEnum.Validation; ValidationErrors = validationErrors; - BrokenBusinessRuleException = null; + Exception = null; } private CommandResult(CommandErrorEnum error) @@ -82,7 +104,7 @@ private CommandResult(CommandErrorEnum error) OperationResult = null; Error = error; ValidationErrors = new Dictionary(); - BrokenBusinessRuleException = null; + Exception = null; } private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException) @@ -90,13 +112,33 @@ private CommandResult(BrokenBusinessRuleException brokenBusinessRuleException) OperationResult = null; Error = CommandErrorEnum.BrokenBusinessRule; ValidationErrors = new Dictionary(); - BrokenBusinessRuleException = brokenBusinessRuleException; + Exception = brokenBusinessRuleException; + } + + private CommandResult(ConcurrencyException concurrencyException) + { + Error = CommandErrorEnum.ConcurrencyConflict; + ValidationErrors = new Dictionary(); + Exception = concurrencyException; + } + + public CommandResult(Exception exception) + { + Error = CommandErrorEnum.UnknownException; + ValidationErrors = new Dictionary(); + Exception = exception; } internal static CommandResult Validation(IDictionary validationErrors) => new CommandResult(validationErrors); internal static CommandResult BrokenBusinessRule(BrokenBusinessRuleException brokenBusinessRuleException) => new CommandResult(brokenBusinessRuleException); + internal static CommandResult ConcurrencyConflict(ConcurrencyException concurrencyException) => new CommandResult(concurrencyException); + + internal static CommandResult OperationCanceled() => new CommandResult(CommandErrorEnum.OperationCanceled); + + internal static CommandResult UnknownException(Exception exception) => new CommandResult(exception); + public static CommandResult Ok(TOperationResult operationResult) => new CommandResult(operationResult); public static CommandResult NotFound => new CommandResult(CommandErrorEnum.NotFound); diff --git a/source/EasyWay/Internals/Commands/CommandErrorEnum.cs b/source/EasyWay/Internals/Commands/CommandErrorEnum.cs new file mode 100644 index 0000000..201297c --- /dev/null +++ b/source/EasyWay/Internals/Commands/CommandErrorEnum.cs @@ -0,0 +1,14 @@ +namespace EasyWay.Internals.Commands +{ + internal enum CommandErrorEnum : byte + { + None = 1, + Validation = 2, + BrokenBusinessRule = 3, + ConcurrencyConflict = 4, + OperationCanceled = 5, + NotFound = 6, + Forbidden = 7, + UnknownException = 8 + } +} diff --git a/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs b/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs index 280a38f..9aeef82 100644 --- a/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs +++ b/source/EasyWay/Internals/Commands/Commands/CommandExecutor.cs @@ -47,13 +47,25 @@ public async Task Execute(TCommand command, Ca commandResult = await _serviceProvider .GetRequiredService>() .Handle(command); + + await _unitOfWork.Commit(); } catch (BrokenBusinessRuleException brokenBusinessRuleException) { return CommandResult.BrokenBusinessRule(brokenBusinessRuleException); } - - await _unitOfWork.Commit(); + catch (ConcurrencyException concurrencyException) + { + return CommandResult.ConcurrencyConflict(concurrencyException); + } + catch (OperationCanceledException) + { + return CommandResult.OperationCanceled(); + } + catch (Exception exception) + { + return CommandResult.UnknownException(exception); + } return commandResult; } diff --git a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs deleted file mode 100644 index 6ab58db..0000000 --- a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandErrorEnum.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace EasyWay.Internals.Commands.CommandsWithResult -{ - internal enum CommandErrorEnum - { - None, - Validation, - BrokenBusinessRule, - NotFound, - Forbidden, - } -} diff --git a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs index 16d6b58..159d8b7 100644 --- a/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs +++ b/source/EasyWay/Internals/Commands/CommandsWithResult/CommandWithOperationResultExecutor.cs @@ -48,13 +48,25 @@ public async Task> Command.BrokenBusinessRule(brokenBusinessRuleException); } - - await _unitOfWork.Commit(); + catch (ConcurrencyException concurrencyException) + { + return CommandResult.ConcurrencyConflict(concurrencyException); + } + catch (OperationCanceledException) + { + return CommandResult.OperationCanceled(); + } + catch (Exception exception) + { + return CommandResult.UnknownException(exception); + } return commandResult; }