SwapDude/SWAD.API/Middlewares/ExceptionMiddleware.cs
Lisoveliy aebe654c38
Some checks are pending
Deploy / update (push) Waiting to run
Build Project .NET / build (push) Waiting to run
chore: init commit from GitHub
2025-05-12 19:44:33 +03:00

90 lines
3.2 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
namespace SWAD.API.Middlewares;
/// <summary>
/// DONT TOUCH THAT!!! Generate good messages for responses and handle to logger exceptions
/// </summary>
/// <param Name="logger"></param>
/// <param Name="env"></param>
/// <param Name="next"></param>
public class ExceptionMiddleware(ILogger<ExceptionMiddleware> logger, IWebHostEnvironment env, RequestDelegate next)
{
private const string DefaultMessage = "An unexpected error has occurred, dude.";
private const string ResponseStartedMessage =
"The response has already started, the http status code middleware will not be executed.";
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await next(httpContext);
}
catch (Exception e)
{
if (httpContext.Response.HasStarted)
{
logger.LogWarning(ResponseStartedMessage);
throw;
}
var id = string.IsNullOrEmpty(httpContext?.TraceIdentifier)
? Guid.NewGuid().ToString()
: httpContext.TraceIdentifier;
logger.LogError($"An exception was thrown during the request, dude. " +
$"{id} \n{(env.IsDevelopment() ? "strcstart:\n" + e : e.GetType().Name) + e.StackTrace + e.Source + e.InnerException}");
// logger.LogError($"An exception was thrown during the request, dude. " +
// $"{id} \n{(env.IsDevelopment() ? "strcstart:\n" + e : e.GetType().Name)}");
await ProblemExceptionResponse(httpContext!, e, id);
}
}
private async Task ProblemExceptionResponse(HttpContext httpContext, Exception e, string id)
{
//Create problem
var problem = new ProblemDetails
{
Title = DefaultMessage,
Status = StatusCodes.Status500InternalServerError
};
//Add stacktrace if env is development
if (env.IsDevelopment())
{
problem.Detail = $"{e.Message} in {e.GetType().Name}";
var lines = new List<string> { "Next strings is stacktrace. Enjoy, dude :)", "strcstart:" }
.Concat(e.StackTrace!.Split("\r\n").Select(e => e.TrimStart()));
problem.Extensions.Add(new KeyValuePair<string, object?>("StackTrace", lines));
}
else
{
problem.Detail = $"{e.Message} in {e}";
}
switch (e)
{
case NotImplementedException:
problem.Status = StatusCodes.Status501NotImplemented;
break;
case ValidationException ve:
return;
}
var jsonResponse = JsonSerializer
.Serialize(problem, new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
});
httpContext.Response.StatusCode = problem.Status ?? StatusCodes.Status500InternalServerError;
httpContext.Response.ContentType = "application/problem+json";
await httpContext.Response
.WriteAsync(jsonResponse);
}
}