From 83277af66f68379fcd7b6bfb5d00a504dcb46f6a Mon Sep 17 00:00:00 2001 From: Dave Roman <43916038+MrDave1999@users.noreply.github.com> Date: Tue, 18 Apr 2023 13:01:22 -0500 Subject: [PATCH] Added support for handle database errors (#184) * Added `EntityFramework.Exceptions` package * Changed the type of the `ResponseBase.Errors` property to `IEnumerable` * Error has been handled when the unique restriction is violated --- src/Constants/ResponseMessages.cs | 2 ++ src/DataAccess/AppDbContext.cs | 1 + src/DentallApp.csproj | 1 + src/Extensions/MvcBuilderExtensions.cs | 4 ++-- src/GlobalUsings.cs | 2 ++ src/Middlewares/ExceptionHandlingMiddleware.cs | 6 ++++++ src/Responses/ResponseBase.cs | 2 +- 7 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Constants/ResponseMessages.cs b/src/Constants/ResponseMessages.cs index 1593336b..6d386ef2 100644 --- a/src/Constants/ResponseMessages.cs +++ b/src/Constants/ResponseMessages.cs @@ -11,6 +11,8 @@ public class ResponseMessages public const string UnexpectedErrorMessage = "Hubo un error inesperado, por favor intente de nuevo."; public const string UnexpectedErrorsMessage = "Se encontraron errores inesperados, por favor intente de nuevo."; + public const string UniqueConstraintViolatedMessage = "Se detectó una violación a una restricción única (UNIQUE INDEX). " + + "Por favor, no envíe una entrada duplicada."; public const string DirectLineTokenFailedMessage = "Direct Line token API call failed."; public const string InactiveUserAccountMessage = "Cuenta de usuario inactiva."; diff --git a/src/DataAccess/AppDbContext.cs b/src/DataAccess/AppDbContext.cs index a15fa731..008ae7f7 100644 --- a/src/DataAccess/AppDbContext.cs +++ b/src/DataAccess/AppDbContext.cs @@ -12,6 +12,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) // See https://github.com/DentallApp/back-end/issues/25. warnings.Ignore(CoreEventId.PossibleIncorrectRequiredNavigationWithQueryFilterInteractionWarning)); optionsBuilder.AddDelegateDecompiler(); + optionsBuilder.UseExceptionProcessor(); } protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/src/DentallApp.csproj b/src/DentallApp.csproj index 487e9c97..5562ced0 100755 --- a/src/DentallApp.csproj +++ b/src/DentallApp.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Extensions/MvcBuilderExtensions.cs b/src/Extensions/MvcBuilderExtensions.cs index ba0f97d2..89f9f8ad 100644 --- a/src/Extensions/MvcBuilderExtensions.cs +++ b/src/Extensions/MvcBuilderExtensions.cs @@ -16,11 +16,11 @@ where state.Value.Errors.Count > 0 ErrorMessages = state.Value.Errors.Select(modelError => modelError.ErrorMessage) }).ToDictionary(x => x.Key, x => x.ErrorMessages); - var result = new Response + var result = new { Success = false, Message = InvalidModelStateMessage, - Errors = errors + Errors = errors }; return new BadRequestObjectResult(result); }; diff --git a/src/GlobalUsings.cs b/src/GlobalUsings.cs index 443051bf..75b36edd 100644 --- a/src/GlobalUsings.cs +++ b/src/GlobalUsings.cs @@ -143,6 +143,8 @@ global using SendGrid.Helpers.Mail; global using SendGrid.Extensions.DependencyInjection; +global using EntityFramework.Exceptions.Common; +global using EntityFramework.Exceptions.MySQL.Pomelo; global using DelegateDecompiler; global using FileTypeChecker; global using FileTypeChecker.Extensions; diff --git a/src/Middlewares/ExceptionHandlingMiddleware.cs b/src/Middlewares/ExceptionHandlingMiddleware.cs index 1674dcfe..b7dc065b 100644 --- a/src/Middlewares/ExceptionHandlingMiddleware.cs +++ b/src/Middlewares/ExceptionHandlingMiddleware.cs @@ -34,6 +34,12 @@ public async Task InvokeAsync(HttpContext context) Message = UnexpectedErrorMessage }; + if (exception is UniqueConstraintException) + { + context.Response.StatusCode = (int)HttpStatusCode.BadRequest; + response.Errors = new[] { UniqueConstraintViolatedMessage }; + } + await context.Response.WriteAsJsonAsync(response); } } diff --git a/src/Responses/ResponseBase.cs b/src/Responses/ResponseBase.cs index 3aa328d7..ce830004 100644 --- a/src/Responses/ResponseBase.cs +++ b/src/Responses/ResponseBase.cs @@ -4,7 +4,7 @@ public class ResponseBase { public bool Success { get; set; } public string Message { get; set; } - public IDictionary> Errors { get; set; } + public IEnumerable Errors { get; set; } public ResponseBase() {