90 lines
3.2 KiB
C#
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);
|
|
}
|
|
} |