diff --git a/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs b/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs index 4f1cec3..c72fa25 100644 --- a/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs +++ b/DebugProbe.AspNetCore/Middleware/DebugProbeMiddleware.cs @@ -1,4 +1,4 @@ -using System.Diagnostics; +using System.Diagnostics; using System.Text; using DebugProbe.AspNetCore.Models; using DebugProbe.AspNetCore.Options; @@ -58,14 +58,18 @@ public async Task Invoke(HttpContext context, DebugEntryStore store) var started = Stopwatch.StartNew(); var exception = false; + string? exceptionMessage = null; + string? exceptionStackTrace = null; try { await _next(context); } - catch + catch (Exception ex) { exception = true; + exceptionMessage = ex.Message; + exceptionStackTrace = ex.StackTrace; throw; } finally @@ -100,25 +104,25 @@ public async Task Invoke(HttpContext context, DebugEntryStore store) $"{context.Request.Path}{context.Request.QueryString}", RequestBody = Trim(requestBody), - // Response ResponseBody = Trim(responseBody), + // Exception + ExceptionMessage = exceptionMessage, + ExceptionStackTrace = Trim(exceptionStackTrace, max: 4000), // Headers Headers = context.Request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString()), - // Other Timestamp = DateTime.UtcNow, - }); } } - private string Trim(string value, int max = 2000) + private string Trim(string? value, int max = 2000) { - if (string.IsNullOrEmpty(value)) return value; + if (string.IsNullOrEmpty(value)) return value ?? string.Empty; return value.Length <= max ? value : value.Substring(0, max); } -} \ No newline at end of file +} diff --git a/DebugProbe.AspNetCore/Models/DebugEntry.cs b/DebugProbe.AspNetCore/Models/DebugEntry.cs index fa7fe93..e101f2d 100644 --- a/DebugProbe.AspNetCore/Models/DebugEntry.cs +++ b/DebugProbe.AspNetCore/Models/DebugEntry.cs @@ -1,4 +1,4 @@ -namespace DebugProbe.AspNetCore.Models; +namespace DebugProbe.AspNetCore.Models; public class DebugEntry { @@ -19,9 +19,13 @@ public class DebugEntry public long ResponseSize { get; set; } public string ResponseBody { get; set; } = default!; + // Exception (captured when middleware catches an unhandled error) + public string? ExceptionMessage { get; set; } + public string? ExceptionStackTrace { get; set; } + // Headers public Dictionary Headers { get; set; } = new(); // Metadata public DateTimeOffset Timestamp { get; set; } -} \ No newline at end of file +}