Files
public-valetax/Middleware/ExceptionHandlingMiddleware.cs
2025-12-26 16:40:32 +03:00

74 lines
2.7 KiB
C#

using System.Text.Json;
using public_valetax.Exceptions;
using public_valetax.Repositories;
namespace public_valetax.Middleware
{
public class ExceptionHandlingMiddleware(RequestDelegate _next, ILogger<ExceptionHandlingMiddleware> _logger)
{
public async Task InvokeAsync(HttpContext context, IJournalRepository journalRepository)
{
try
{
if (context.Request.ContentLength > 0)
{
context.Request.EnableBuffering();
}
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "An unhandled exception occurred");
// Generate event ID
var eventId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// Capture request details
var queryParameters = context.Request.QueryString.ToString();
string? bodyParameters = null;
// Try to capture body parameters (be careful not to consume the stream multiple times)
if (context.Request.ContentLength > 0)
{
context.Request.Body.Position = 0; // Reset for next middleware
using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
bodyParameters = await reader.ReadToEndAsync();
context.Request.Body.Position = 0; // Reset for next middleware
}
// Log to journal
await journalRepository.CreateJournalEntryAsync(
eventId,
ex.GetType().Name,
ex.Message,
queryParameters,
bodyParameters,
ex.StackTrace);
// Handle specific exception types
await HandleExceptionAsync(context, ex, eventId);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception exception, long eventId)
{
var response = new
{
type = exception is SecureException ? "Secure" : "Exception",
id = eventId.ToString(),
data = new
{
message = exception is SecureException
? exception.Message
: $"Internal server error ID = {eventId}"
}
};
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
var jsonResponse = JsonSerializer.Serialize(response);
await context.Response.WriteAsync(jsonResponse);
}
}
}