90 lines
3.0 KiB
C#
90 lines
3.0 KiB
C#
using CPRNIMS.Infrastructure.Database;
|
|
using CPRNIMS.Infrastructure.Entities.Common;
|
|
using CPRNIMS.WebApi.Exceptions;
|
|
using System.Security.Claims;
|
|
using System.Text.Json;
|
|
|
|
namespace CPRNIMS.Middleware
|
|
{
|
|
public sealed class GlobalExceptionMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly ILogger<GlobalExceptionMiddleware> _logger;
|
|
private readonly IWebHostEnvironment _env;
|
|
private readonly IServiceScopeFactory _scopeFactory;
|
|
public GlobalExceptionMiddleware(
|
|
RequestDelegate next,
|
|
ILogger<GlobalExceptionMiddleware> logger,
|
|
IWebHostEnvironment env,
|
|
IServiceScopeFactory scopeFactory)
|
|
{
|
|
_next = next;
|
|
_logger = logger;
|
|
_env = env;
|
|
_scopeFactory = scopeFactory;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
try
|
|
{
|
|
await _next(context);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Unhandled exception");
|
|
|
|
await LogToDatabaseAsync(context, ex);
|
|
await HandleResponseAsync(context, ex);
|
|
}
|
|
}
|
|
|
|
private async Task LogToDatabaseAsync(HttpContext context, Exception ex)
|
|
{
|
|
using var scope = _scopeFactory.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<NonInventoryDbContext>();
|
|
|
|
var errorLog = new ErrorLog
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Path = context.Request.Path,
|
|
HttpMethod = context.Request.Method,
|
|
QueryString = context.Request.QueryString.Value,
|
|
StatusCode = context.Response.StatusCode,
|
|
ExceptionType = ex.GetType().FullName!,
|
|
Message = ex.Message,
|
|
StackTrace = ex.StackTrace,
|
|
UserId = context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value,
|
|
IpAddress = context.Connection.RemoteIpAddress?.ToString(),
|
|
CreatedAt = DateTime.UtcNow
|
|
};
|
|
|
|
db.ErrorLogs.Add(errorLog);
|
|
await db.SaveChangesAsync();
|
|
}
|
|
|
|
private async Task HandleResponseAsync(HttpContext context, Exception ex)
|
|
{
|
|
context.Response.ContentType = "application/json";
|
|
|
|
context.Response.StatusCode = ex switch
|
|
{
|
|
AppException app => app.StatusCode,
|
|
ArgumentException => StatusCodes.Status400BadRequest,
|
|
UnauthorizedAccessException => StatusCodes.Status401Unauthorized,
|
|
_ => StatusCodes.Status500InternalServerError
|
|
};
|
|
|
|
var response = new
|
|
{
|
|
success = false,
|
|
message = _env.IsDevelopment()
|
|
? ex.Message
|
|
: "An unexpected error occurred"
|
|
};
|
|
|
|
await context.Response.WriteAsync(JsonSerializer.Serialize(response));
|
|
}
|
|
}
|
|
}
|