| | | 1 | | using System.Data.SqlTypes; |
| | | 2 | | using System.Net; |
| | | 3 | | using System.Text.Json; |
| | | 4 | | using TicTacToeApp.API.Exceptions; |
| | | 5 | | using TicTacToeApp.API.Response; |
| | | 6 | | |
| | | 7 | | namespace TicTacToeApp.API.Middleware; |
| | | 8 | | |
| | | 9 | | public sealed class ExceptionHandlerMiddleware |
| | | 10 | | { |
| | | 11 | | private readonly RequestDelegate _next; |
| | | 12 | | private readonly ILogger<ExceptionHandlerMiddleware> _logger; |
| | | 13 | | private readonly IHostEnvironment _env; |
| | | 14 | | |
| | 0 | 15 | | public ExceptionHandlerMiddleware( |
| | 0 | 16 | | RequestDelegate next, |
| | 0 | 17 | | ILogger<ExceptionHandlerMiddleware> logger, |
| | 0 | 18 | | IHostEnvironment env |
| | 0 | 19 | | ) |
| | | 20 | | { |
| | 0 | 21 | | _env = env; |
| | 0 | 22 | | _logger = logger; |
| | 0 | 23 | | _next = next; |
| | 0 | 24 | | } |
| | | 25 | | |
| | | 26 | | // когда мы работает с middleware у нас есть доступ к контексту HttpContext |
| | | 27 | | public async Task InvokeAsync(HttpContext context) |
| | | 28 | | { |
| | | 29 | | try |
| | | 30 | | { |
| | | 31 | | // мы получим контекст http и передадим его дальше другому middleware вниз |
| | 0 | 32 | | await _next(context); |
| | 0 | 33 | | } |
| | 0 | 34 | | catch (Exception ex) |
| | | 35 | | { |
| | 0 | 36 | | _logger.LogError(ex, ex.Message); |
| | 0 | 37 | | await ConvertExceptionAsync(context, ex); |
| | | 38 | | } |
| | 0 | 39 | | } |
| | | 40 | | |
| | | 41 | | private Task ConvertExceptionAsync(HttpContext context, System.Exception exception) |
| | | 42 | | { |
| | 0 | 43 | | context.Response.ContentType = "application/json"; |
| | 0 | 44 | | var httpStatusCode = HttpStatusCode.InternalServerError; |
| | | 45 | | |
| | 0 | 46 | | var message = string.Empty; |
| | 0 | 47 | | var messagedetail = string.Empty; |
| | | 48 | | |
| | | 49 | | switch (exception) |
| | | 50 | | { |
| | | 51 | | case Npgsql.PostgresException ex: |
| | 0 | 52 | | httpStatusCode = HttpStatusCode.InternalServerError; |
| | 0 | 53 | | message = ex.Message; |
| | 0 | 54 | | messagedetail = ex.StackTrace?.ToString(); |
| | 0 | 55 | | break; |
| | | 56 | | case BadHttpRequestException badRequestException: |
| | 0 | 57 | | httpStatusCode = HttpStatusCode.BadRequest; |
| | 0 | 58 | | message = badRequestException.Message; |
| | 0 | 59 | | messagedetail = badRequestException.StackTrace?.ToString(); |
| | 0 | 60 | | break; |
| | | 61 | | |
| | | 62 | | case NotFoundException ex: |
| | 0 | 63 | | httpStatusCode = HttpStatusCode.NotFound; |
| | 0 | 64 | | message = ex.Message; |
| | 0 | 65 | | messagedetail = ex.StackTrace?.ToString(); |
| | 0 | 66 | | break; |
| | | 67 | | |
| | | 68 | | case ArgumentException ex: |
| | 0 | 69 | | httpStatusCode = HttpStatusCode.BadRequest; |
| | 0 | 70 | | message = ex.Message; |
| | 0 | 71 | | messagedetail = ex.StackTrace?.ToString(); |
| | 0 | 72 | | break; |
| | | 73 | | |
| | | 74 | | case SqlTypeException sqlEx: |
| | 0 | 75 | | httpStatusCode = HttpStatusCode.BadRequest; |
| | 0 | 76 | | message = sqlEx.Message; |
| | 0 | 77 | | messagedetail = sqlEx.StackTrace?.ToString(); |
| | 0 | 78 | | break; |
| | | 79 | | |
| | | 80 | | case Exception ex: |
| | 0 | 81 | | httpStatusCode = HttpStatusCode.InternalServerError; |
| | 0 | 82 | | message = ex.Message; |
| | 0 | 83 | | messagedetail = ex.StackTrace?.ToString(); |
| | | 84 | | break; |
| | | 85 | | } |
| | | 86 | | |
| | 0 | 87 | | context.Response.StatusCode = (int)httpStatusCode; |
| | | 88 | | |
| | 0 | 89 | | var response = _env.IsDevelopment() |
| | 0 | 90 | | ? new ErrorResponse(context.Response.StatusCode.ToString(), message, messagedetail) |
| | 0 | 91 | | : new ErrorResponse(context.Response.StatusCode.ToString(), "Internal Server Error"); |
| | | 92 | | |
| | 0 | 93 | | var options = new JsonSerializerOptions() |
| | 0 | 94 | | { |
| | 0 | 95 | | PropertyNamingPolicy = JsonNamingPolicy.CamelCase, |
| | 0 | 96 | | }; |
| | 0 | 97 | | var result = JsonSerializer.Serialize(response, options); |
| | 0 | 98 | | return context.Response.WriteAsync(result); |
| | | 99 | | } |
| | | 100 | | } |