From 55e82425a9ee63bea917a95cfe486bd503f63d1d Mon Sep 17 00:00:00 2001 From: shept Date: Fri, 18 Apr 2025 15:15:32 +0500 Subject: [PATCH] say NO to try-catch in controllers - added ExceptionsMiddleware.cs - added more Exception types - removed all exceptions logic in controllers --- .../Controllers/AuthController.cs | 18 ++----- .../Middlewares/ExceptionsMiddleware.cs | 49 +++++++++++++++++++ SurveyBackend/SurveyBackend.API/Program.cs | 3 ++ .../Services/IAuthorizationService.cs | 2 +- .../Services/IUserService.cs | 2 +- .../Exceptions/NotFoundException.cs | 10 ++++ .../Services/AuthorizationService.cs | 6 +-- .../Services/UserService.cs | 5 +- 8 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 SurveyBackend/SurveyBackend.API/Middlewares/ExceptionsMiddleware.cs create mode 100644 SurveyBackend/SurveyBackend.Services/Exceptions/NotFoundException.cs diff --git a/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs b/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs index e0ecc0b..7a2e115 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; +using SurveyBackend.Core.Services; using SurveyBackend.DTOs; using SurveyBackend.Mappers.UserDTOs; -using SurveyBackend.Services.Services; namespace SurveyBackend.Controllers; @@ -9,9 +9,9 @@ namespace SurveyBackend.Controllers; [Route("auth")] public class AuthController : ControllerBase { - private readonly AuthorizationService _authorizationService; + private readonly IAuthorizationService _authorizationService; - public AuthController(AuthorizationService authorizationService) + public AuthController(IAuthorizationService authorizationService) { _authorizationService = authorizationService; } @@ -20,21 +20,13 @@ public class AuthController : ControllerBase public async Task LogIn([FromBody] UserLoginDto loginData) { var token = await _authorizationService.LogInUser(loginData.Email, loginData.Password); - return token is null ? Unauthorized() : Ok(new { token = token }); + return Ok(new { token = token }); } [HttpPost("register")] public async Task Register([FromBody] UserRegistrationDto registerData) { - try - { - await _authorizationService.RegisterUser(UserRegistrationMapper.UserRegistrationToModel(registerData)); - } - catch (Exception ex) - { - return BadRequest(ex.Message); - } - + await _authorizationService.RegisterUser(UserRegistrationMapper.UserRegistrationToModel(registerData)); return Ok(); } } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Middlewares/ExceptionsMiddleware.cs b/SurveyBackend/SurveyBackend.API/Middlewares/ExceptionsMiddleware.cs new file mode 100644 index 0000000..65c94f8 --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/Middlewares/ExceptionsMiddleware.cs @@ -0,0 +1,49 @@ +using SurveyBackend.Services.Exceptions; + +namespace SurveyBackend.Middlewares; + +public class ExceptionsMiddleware +{ + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + public ExceptionsMiddleware(RequestDelegate next, ILogger logger) + { + _next = next; + _logger = logger; + } + + public async Task InvokeAsync(HttpContext context) + { + try + { + await _next(context); + } + catch (ServiceException ex) + { + context.Response.StatusCode = ex.StatusCode; + context.Response.ContentType = "application/json"; + + var response = new + { + error = ex.Message + }; + + await context.Response.WriteAsJsonAsync(response); + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + + context.Response.StatusCode = 500; + context.Response.ContentType = "application/json"; + + var response = new + { + error = "Internal Server Error. GG WP, request bub fix" + }; + + await context.Response.WriteAsJsonAsync(response); + } + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Program.cs b/SurveyBackend/SurveyBackend.API/Program.cs index d56c7ab..6a2bf3f 100644 --- a/SurveyBackend/SurveyBackend.API/Program.cs +++ b/SurveyBackend/SurveyBackend.API/Program.cs @@ -7,6 +7,7 @@ using SurveyBackend.Core.Services; using SurveyBackend.Infrastructure; using SurveyBackend.Infrastructure.Data; using SurveyBackend.Infrastructure.Repositories; +using SurveyBackend.Middlewares; using SurveyBackend.Services; using SurveyBackend.Services.Services; using SurveyLib.Core.Repositories; @@ -71,6 +72,8 @@ public class Program app.UseSwaggerUI(); } + app.UseMiddleware(); + app.UseAuthentication(); app.UseAuthorization(); diff --git a/SurveyBackend/SurveyBackend.Core/Services/IAuthorizationService.cs b/SurveyBackend/SurveyBackend.Core/Services/IAuthorizationService.cs index 1767ce2..2af6ec7 100644 --- a/SurveyBackend/SurveyBackend.Core/Services/IAuthorizationService.cs +++ b/SurveyBackend/SurveyBackend.Core/Services/IAuthorizationService.cs @@ -4,6 +4,6 @@ namespace SurveyBackend.Core.Services; public interface IAuthorizationService { - public Task LogInUser(string email, string password); + public Task LogInUser(string email, string password); public Task RegisterUser(User user); } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Core/Services/IUserService.cs b/SurveyBackend/SurveyBackend.Core/Services/IUserService.cs index bb40cdf..c341a4a 100644 --- a/SurveyBackend/SurveyBackend.Core/Services/IUserService.cs +++ b/SurveyBackend/SurveyBackend.Core/Services/IUserService.cs @@ -4,6 +4,6 @@ namespace SurveyBackend.Core.Services; public interface IUserService { - public Task GetUserByEmail(string email); + public Task GetUserByEmail(string email); public Task CreateUserAsync(User user); } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Exceptions/NotFoundException.cs b/SurveyBackend/SurveyBackend.Services/Exceptions/NotFoundException.cs new file mode 100644 index 0000000..a5e5739 --- /dev/null +++ b/SurveyBackend/SurveyBackend.Services/Exceptions/NotFoundException.cs @@ -0,0 +1,10 @@ +namespace SurveyBackend.Services.Exceptions; + +public class NotFoundException : ServiceException +{ + public override int StatusCode => 404; + + public NotFoundException(string message) : base(message) + { + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/AuthorizationService.cs b/SurveyBackend/SurveyBackend.Services/Services/AuthorizationService.cs index 05acef2..4a0e006 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/AuthorizationService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/AuthorizationService.cs @@ -16,12 +16,12 @@ public class AuthorizationService : IAuthorizationService _passwordHasher = passwordHasher; } - public async Task LogInUser(string email, string password) + public async Task LogInUser(string email, string password) { var user = await _userService.GetUserByEmail(email); - if (user is null || !_passwordHasher.Verify(password, user.Password)) + if (!_passwordHasher.Verify(password, user.Password)) { - throw new UnauthorizedException("Email or password is incorrect."); + throw new UnauthorizedException("Password is incorrect."); } var token = TokenHelper.GetAuthToken(user); diff --git a/SurveyBackend/SurveyBackend.Services/Services/UserService.cs b/SurveyBackend/SurveyBackend.Services/Services/UserService.cs index 8ae531d..eea4ee7 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/UserService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/UserService.cs @@ -1,6 +1,7 @@ using SurveyBackend.Core.Models; using SurveyBackend.Core.Repositories; using SurveyBackend.Core.Services; +using SurveyBackend.Services.Exceptions; namespace SurveyBackend.Services.Services; @@ -13,9 +14,9 @@ public class UserService : IUserService _userRepository = userRepository; } - public async Task GetUserByEmail(string email) + public async Task GetUserByEmail(string email) { - return await _userRepository.GetUserByEmail(email); + return await _userRepository.GetUserByEmail(email) ?? throw new NotFoundException("Email not found"); } public async Task CreateUserAsync(User user)