Author: Dasan G | Date: May 15, 2025 | Category: ASP.NET Core API
When operating high-throughput production Web APIs, unhandled exceptions can disrupt system stability and hide critical bug tracebacks. Standard generic 500 server error pages lack necessary context. To diagnose production issues efficiently, developers need User-Based Global Error Logging that captures:
ProblemDetails JSON format for clean client responses.In modern .NET Core, implementing IExceptionHandler provides a centralized pipeline mechanism to catch and record all unhandled middleware exceptions.
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
public class UserGlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger<UserGlobalExceptionHandler> _logger;
public UserGlobalExceptionHandler(ILogger<UserGlobalExceptionHandler> logger)
{
_logger = logger;
}
public async ValueTask<bool> TryHandleAsync(
HttpContext httpContext,
Exception exception,
CancellationToken cancellationToken)
{
// 1. Extract User Identity Details
var userId = httpContext.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "Anonymous";
var userEmail = httpContext.User?.FindFirst(ClaimTypes.Email)?.Value ?? "N/A";
var clientIp = httpContext.Connection.RemoteIpAddress?.ToString() ?? "Unknown IP";
// 2. Capture Request Telemetry
var requestPath = httpContext.Request.Path;
var requestMethod = httpContext.Request.Method;
var queryString = httpContext.Request.QueryString.HasValue ? httpContext.Request.QueryString.Value : "None";
// 3. Log Structured Critical Error Log
_logger.LogError(
exception,
"CRITICAL API EXCEPTION | User: {UserId} ({UserEmail}) | IP: {ClientIp} | Route: {Method} {Path}?{Query} | Exception: {Message}",
userId, userEmail, clientIp, requestMethod, requestPath, queryString, exception.Message);
// 4. Construct RFC 7807 Standardized ProblemDetails JSON
var problemDetails = new ProblemDetails
{
Status = StatusCodes.Status500InternalServerError,
Title = "An unexpected server error occurred.",
Detail = "Our technical team has been notified. Please quote the reference ID below when contacting support.",
Instance = $"{requestMethod} {requestPath}"
};
problemDetails.Extensions["referenceId"] = Guid.NewGuid().ToString();
problemDetails.Extensions["timestamp"] = DateTime.UtcNow;
problemDetails.Extensions["userRef"] = userId;
httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);
// Return true to signify the exception has been safely handled
return true;
}
}
Register the custom handler and exception handling middleware in Program.cs:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Register User Global Exception Handler
builder.Services.AddExceptionHandler<UserGlobalExceptionHandler>();
builder.Services.AddProblemDetails();
var app = builder.Build();
// Enable Global Exception Handler Middleware early in the HTTP pipeline
app.UseExceptionHandler();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
When an unhandled error occurs in any controller endpoint, structured logs capture the user reference instantly:
[ERROR] CRITICAL API EXCEPTION | User: USR_9841 (dasan@example.com) | IP: 106.51.72.18 | Route: POST /api/v1/orders?coupon=FALL2025 | Exception: Sequence contains no elements
The client receives a sanitized, secure ProblemDetails JSON response without revealing internal stack traces:
{
"status": 500,
"title": "An unexpected server error occurred.",
"detail": "Our technical team has been notified. Please quote the reference ID below when contacting support.",
"instance": "POST /api/v1/orders",
"referenceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"timestamp": "2025-05-15T14:30:00Z",
"userRef": "USR_9841"
}
Implementing user-based global exception handling transforms debugging from searching through anonymous error dumps to instantly knowing which user triggered the bug, on which route, and under what conditions. This setup drastically reduces MTTR (Mean Time to Resolution) in production enterprise environments.
← Back to Portfolio