June 23 2025
{
"title": "Something went wrong",
"status": 500,
"detail": "Please contact support.",
"instance": "/products/0"
}
{
"title": "Product not found",
"status": 404,
"detail": "No product with ID 42.",
"instance": "/products/42"
}
public record Product(int Id, string Name);
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionHandlingMiddleware> _logger;
public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception occurred");
var problem = new ProblemDetails
{
Title = "An unexpected error occurred.",
Status = StatusCodes.Status500InternalServerError,
Detail = "Please contact support.",
Instance = context.Request.Path
};
context.Response.ContentType = "application/problem+json";
context.Response.StatusCode = problem.Status.Value;
var json = JsonSerializer.Serialize(problem);
await context.Response.WriteAsync(json);
}
}
}
using Microsoft.AspNetCore.Mvc;
using ProblemDetailsMinimalApi;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Use custom error handling middleware
app.UseMiddleware<ExceptionHandlingMiddleware>();
// In-memory data for testing
var products = new List<Product>
{
new Product(1, "Laptop"),
new Product(2, "Phone"),
new Product(3, "Keyboard")
};
// GET /products/{id}
app.MapGet("/products/{id:int}", (int id, HttpContext http) =>
{
if (id <= 0)
throw new ArgumentOutOfRangeException(nameof(id), "Product ID must be greater than zero.");
var product = products.FirstOrDefault(p => p.Id == id);
if (product is null)
{
var notFoundProblem = new ProblemDetails
{
Title = "Product not found",
Status = StatusCodes.Status404NotFound,
Detail = $"No product found with ID {id}.",
Instance = http.Request.Path
};
return Results.Problem(
title: notFoundProblem.Title,
detail: notFoundProblem.Detail,
statusCode: notFoundProblem.Status,
instance: notFoundProblem.Instance
);
}
return Results.Ok(product);
});
app.Run();
public class CustomProblemDetails : ProblemDetails
{
public string ErrorCode { get; set; } = default!;
}
1. Design Patterns that Deliver
This isn’t just another design patterns book. Dive into real-world examples and practical solutions to real problems in real applications.Check out it here.
Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.
Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.
Join 15,250+ subscribers to improve your .NET Knowledge.
Subscribe to the TheCodeMan.net and be among the 15,250+ subscribers gaining practical tips and resources to enhance your .NET expertise.