Roadmap › Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type › Module: Infrastructure Errors and Resilience
Lessons in this course (9)
9. Custom error pages, error codes and user-friendly messages
Intermediate★ Must knowLesson 9 of 9
Principles for what users see:
- Clear, polite message + what to do next ("We couldn't save your order. Please try again in a minute.").
- A reference/correlation id the user can quote to support — the same id is in the logs.
- No stack traces, SQL, server names or file paths (information disclosure).
- Correct HTTP status codes (404 page returns 404, not 200).
- Stable error codes for APIs (
"errorCode": "credit_limit_exceeded") so clients can react without parsing text; localise messages on the client.
ASP.NET Core MVC error pages:
csharp
app.UseExceptionHandler("/Error"); // 500s → ErrorController
app.UseStatusCodePagesWithReExecute("/Error/{0}"); // 404/403 → same controller, original URL kept
public class ErrorController : Controller
{
[Route("Error/{code:int?}")]
public IActionResult Index(int? code)
{
var feature = HttpContext.Features.Get<IExceptionHandlerPathFeature>(); // original path + exception (log it)
ViewBag.RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
return code switch { 404 => View("NotFound"), 403 => View("Forbidden"), _ => View("ServerError") };
}
}ProblemDetails (RFC 9457) for APIs:
json
{
"type": "https://shop.example.com/errors/credit-limit",
"title": "Business rule violated",
"status": 422,
"detail": "Order exceeds the customer's credit limit.",
"instance": "/api/orders/1001/approve",
"errorCode": "credit_limit_exceeded",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
}