Round #342

08 May 2026, 16:52· csharp· qwen2.5-coder-7b-instruct· r13-clean-hints
Complexity
band 0
ZP / UO / OBS
2 / 5 / 1
Journey weight
499
Lightshift ΔL
+0.00

Prompt

Add global exception handling middleware that maps domain exceptions to HTTP status codes

Zero-point index (what the engine surfaced)

ZPI-ZPI-0001 | 2026-05-08T16:52:01Z Add global exception handling middleware that maps domain exceptions to HTTP status codes ZERO POINT — 2 entries (structural invariants) ● hsl(314.84, 100%, 29%) IMiddleware [contract] ● hsl(280.69, 100%, 29%) RequestDelegate [contract] UNOBSERVED — 5 entries (implied truths) ○ hsl(27.69, 100%, 50%) async [feature] ○ hsl(9.23, 100%, 50%) interface [feature] ○ hsl(77.54, 100%, 36%) Routing middleware [function] ○ hsl(83.08, 100%, 42%) ILogger of T injection [function] ○ hsl(31.38, 100%, 42%) Scoped registration [function] OBSERVED — 1 entries (explicit in request) ◉ hsl(86.15, 100%, 22%) global [feature] COMPLEXITY │ 8 entries │ spread: 77° │ band: LOW

Baseline response (no ZPI)

To add global exception handling middleware in a C# ASP.NET Core application that maps domain exceptions to HTTP status codes, you can follow these steps: 1. **Create a custom exception class for your domain exceptions**: This will help you identify and handle specific types of exceptions. 2. **Implement the middleware**: Create a middleware that catches all unhandled exceptions and maps them to appropriate HTTP status codes based on the type of exception. 3. **Register the middleware in the `Startup.cs` file**: Ensure that your middleware is added to the request pipeline so it runs for every request. Here's a step-by-step implementation: ### Step 1: Create Custom Exception Classes First, create custom exception classes for your domain exceptions. For example: ```csharp public class DomainException : Exception { public int StatusCode { get; } public DomainException(string message, int statusCode) : base(message) { StatusCode = statusCode; } } public class NotFoundException : DomainException { public NotFoundException(string message) : base(message, StatusCodes.Status404NotFound) { } } public class BadRequestException : DomainException { public BadRequestException(string message) : base(message, StatusCodes.Status400BadRequest) { } } ``` ### Step 2: Implement the Middleware Create a middleware that catches all unhandled exceptions and maps them to appropriate HTTP status codes: ```csharp public class ExceptionHandlingMiddleware { private readonly RequestDelegate _next; public ExceptionHandlingMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private static Task HandleExceptionAsync(HttpContext context, Exception exception) { var code = StatusCodes.Status500InternalServerError; if (exception is DomainException domainEx) { code = domainEx.StatusCode; } context.Response.ContentType = "application/json"; context.Response.StatusCode = code; return context.Response.WriteAsync(new { error = exception.Message, statusCode = code }.ToString()); } } ``` ### Step 3: Register the Middleware in `Startup.cs` Register your middleware in the `Configure` method of your `Startup.cs` file: ```csharp public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } // Add the custom exception handling middleware app.UseMiddleware<ExceptionHandlingMiddleware>(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } ``` ### Example Usage Now, you can throw your custom domain exceptions in your controllers or services: ```csharp [ApiController] [Route("[controller]")] public class ProductsController : ControllerBase { [HttpGet("{id}")] public IActionResult Get(int id) { if (id == 0) { throw new BadRequestException("Invalid product ID"); } // Simulate a database query that fails if (!ProductExists(id)) { throw new NotFoundException($"Product with ID {id} not found"); } var product = GetProductById(id); return Ok(product); } private bool ProductExists(int id) { // Simulated check return false; } private object GetProductById(int id) { // Simulated product retrieval return new { Id = id, Name = "Sample Product" }; } } ``` With this setup, any unhandled exceptions thrown in your application will be caught by the `ExceptionHandlingMiddleware`, and they will be mapped to appropriate HTTP status codes based on the type of exception.

Enhanced response (with ZPI)

To implement global exception handling middleware that maps domain exceptions to HTTP status codes, we can create a custom middleware. This middleware will catch any exceptions thrown during the request processing and map them to appropriate HTTP status codes based on the type of exception. Here's how you can implement this: 1. **Create the Custom Middleware:** ```csharp using Microsoft.AspNetCore.Http; using System.Net; using System.Threading.Tasks; public class ExceptionHandlingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<ExceptionHandlingMiddleware> _logger; public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger) { _next = next ?? throw new ArgumentNullException(nameof(next)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private static Task HandleExceptionAsync(HttpContext context, Exception exception) { var code = HttpStatusCode.InternalServerError; // 500 if unexpected switch (exception) { case DomainNotFoundException _: code = HttpStatusCode.NotFound; break; case UnauthorizedAccessException _: code = HttpStatusCode.Unauthorized; break; // Add more cases for other domain exceptions } context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)code; return context.Response.WriteAsync(new ErrorDetails { StatusCode = code, Message = exception.Message }.ToString()); } } public class ErrorDetails { public int StatusCode { get; set; } public string Message { get; set; } public override string ToString() { return $"{{\"StatusCode\":{StatusCode},\"Message\":\"{Message}\"}}"; } } ``` 2. **Register the Middleware in `Startup.cs`:** ```csharp public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // Register the custom exception handling middleware app.UseMiddleware<ExceptionHandlingMiddleware>(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } ``` 3. **Define Domain Exceptions:** ```csharp public class DomainNotFoundException : Exception { public DomainNotFoundException(string message) : base(message) { } } public class UnauthorizedAccessException : Exception { public UnauthorizedAccessException(string message) : base(message) { } } ``` ### Explanation: 1. **Custom Middleware (`ExceptionHandlingMiddleware`):** - The middleware catches exceptions thrown during the request processing. - It maps specific domain exceptions to appropriate HTTP status codes. - It logs the exception and returns a JSON response with the error details. 2. **Error Details Class:** - This class is used to format the error response as JSON. 3. **Registration in `Startup.cs`:** - The middleware is registered in the request pipeline so that it runs for every request. This implementation provides a robust way to handle exceptions globally and map them to appropriate HTTP status codes, ensuring that clients receive meaningful error responses.

Grader chain

Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.

V1claude-sonnet-4-6
Same
V4qwen2.5-coder-7b-instruct
Better

Comments

Our grader said what it said. What do you say? Comment as a guest below.

No comments yet. Be the first to say what you make of this round.

← back to all rounds