using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace FinlyticBackend.Middleware;
///
/// Global fallback exception handler for the Gateway (Rules.md ยง11). Converts any unhandled exception that
/// escapes a controller action, hub method, or other endpoint into a standardized RFC 7807 Problem Details
/// response instead of an ad-hoc anonymous error object or a leaked stack trace.
/// Registered via AddExceptionHandler<GlobalExceptionHandler>() and activated by
/// app.UseExceptionHandler() in Program.cs. This only intercepts exceptions thrown while a
/// request is being handled; it has no effect on the fail-fast startup checks in Program.cs
/// (missing/weak JWT:SecretKey, missing ADMIN:DefaultPassword), which throw before
/// builder.Build() - i.e. before this middleware pipeline exists - and are intentionally left
/// unhandled so the host refuses to start.
///
public sealed class GlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger _logger;
public GlobalExceptionHandler(ILogger logger)
{
_logger = logger;
}
///
public async ValueTask TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
_logger.LogError(
exception,
"Unhandled exception while processing {Method} {Path}",
httpContext.Request.Method,
httpContext.Request.Path);
httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
var problemDetailsService = httpContext.RequestServices.GetRequiredService();
return await problemDetailsService.TryWriteAsync(new ProblemDetailsContext
{
HttpContext = httpContext,
Exception = exception,
ProblemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError,
Title = "An unexpected error occurred.",
Detail = "The Gateway encountered an unexpected error while processing the request.",
Type = "https://tools.ietf.org/html/rfc7231#section-6.6.1"
}
});
}
}