Press "Enter" to skip to content

How to handle errors in minimal APIs in ASP.NET Core

In ASP.NET Core 7, Minimal APIs provide a lightweight way to build web APIs with less boilerplate code. However, errors can still happen and you should be able to handle them gracefully.

This article discusses how we can handle errors correctly in minimal API applications in ASP.NET Core 7. To use the code samples provided in this article, you must have Visual Studio 2022 installed on your system. If you don’t already have a copy, you can download Visual Studio 2022 here.

Create a minimal ASP.NET Core 7 Web API project in Visual Studio 2022

First, let’s create an ASP.NET Core 7 project in Visual Studio 2022. Follow these steps:

  1. Start the Visual Studio 2022 IDE.
  2. Click “Create new project”.
  3. In the “Create New Project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Set up your new project” window, specify the name and location of the new project.
  6. Optionally, check the “Place solution and project in the same directory” checkbox, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown below, select “NET 7.0 (Current)” as the framework and uncheck the checkbox that says “Use Drivers…” Leave the “Authentication Type” as “None” (predetermined).
  9. Make sure the “Enable OpenAPI Support”, “Enable Docker”, “Configure for HTTPS”, and “Enable Open API Support” checkboxes are not checked, as we won’t be using any of those features here.
  10. Click Create.

We’ll use this ASP.NET Core 7 Web API project to create a minimal API and implement error handling in the sections below.

Error handling in minimal API applications

Replace the default generated source code of the Program.cs file in the project we created with the following code snippet.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("https://www.infoworld.com/", () => "Hello World!");
app.Map("/error", ()
    => {
            throw new InvalidOperationException("An Error Occurred...");
        });
app.Run();

When you run the app, the text message “Hello World” will be displayed in your web browser. Navigating to the /error endpoint will cause a runtime error and stop the application from running, as shown in Figure 1.

minimum errors apis 01 IDG

Figure 1. A fatal exception in our minimal API application.

There are two built-in mechanisms for handling errors in Minimal API applications, the Developer Exception Page middleware and the Exception Handler middleware. Let’s examine each one in turn.

Using the Developer Exception Page Middleware

To help developers diagnose and fix errors during development, you can use the Developer Exception Page middleware. The Developer Exception Page middleware displays detailed error information in the browser when an exception occurs.

This is an example of how to use the developer exception page middleware in a minimal API.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
//builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
   app.UseDeveloperExceptionPage();
}
app.MapGet("https://www.infoworld.com/", () => "Hello, world!");
app.Run();

In this example, the UseDeveloperExceptionPage method is used to add the middleware to the pipeline. The middleware is enabled only when the app is running in the development environment, which is determined by the app.Environment.IsDevelopment() method.

If an exception occurs within the pipeline, the developer’s exception page middleware catches it and displays a detailed error page in the browser. The error page includes information about the exception, including the stack trace, request details, and environment variables, as shown in Figure 2.

minimum errors apis 02 IDG

Figure 2. The Developer Exception Page middleware in action.

By using the Developer Exception Page middleware, developers can quickly diagnose and fix errors during development.

Also Read:  .NET 8 Preview 2 brings Blazor performance boosts

Using the exception handler middleware

The exception handler middleware catches unhandled exceptions and returns an error response. Typically, you should use this middleware in a non-development environment. This is an example of how to use the exception handler middleware in a minimal API.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp
    => exceptionHandlerApp.Run(async context => await Results.Problem().ExecuteAsync(context)));
app.Map("/error", ()
    => { throw new InvalidOperationException("An Error Occurred..."); });
app.MapGet("https://www.infoworld.com/", () => "Hello, world!");
app.Run();

In this example, the UseExceptionHandler method is used to configure this middleware. The “/error” parameter specifies the endpoint to which the middleware will redirect in case of an exception.

If an unhandled exception occurs within the pipeline, the exception handling middleware catches it and redirects the request to the specified endpoint. Afterwards, the error will be handled and an appropriate error message will be returned.

By using the exception handling middleware, you can easily handle exceptions that occur within the minimal APIs in ASP.NET Core 7. This can help improve the reliability and usability of your API.

Using ProblemDetails for the response format

The ProblemDetails class is a way to include error information details to avoid creating custom error response formats in ASP.NET Core. The AddProblemDetails extension method belonging to the IServiceCollection interface can be used to register a default implementation of IProblemDetailsService.

The following middleware in ASP.NET Core generates HTTP responses from ProblemDetails when you call the AddProblemDetailsMiddleware method in your app.

  • ExceptionHandlerMiddleware – This middleware is used to generate a ProblemDetails response if no custom handler is available.
  • DeveloperExceptionPageMiddleware: The DeveloperExceptionPageMiddleware creates a ProblemDetails response if the Accept HTTP header contains no text/html.
  • StatusCodePagesMiddleware – By default, the StatusCodePagesMiddleware generates responses from ProblemDetails.

The following code list shows how you can use ProblemDetails in your minimal APIs.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
app.Map("/authors/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new Author(id)));
app.Map("/error", ()
=> {
       throw new InvalidOperationException("An Error Occurred...");
   });
app.Run();
public record Author(int Id);

In this example, the /error endpoint extracts the exception information from the HttpContext and creates a ProblemDetails object with the error details. It then sets the response status code and content type, and returns the ProblemDetails object as a JSON response.

Using the status code page middleware to generate a response body

When an ASP.NET Core app encounters HTTP error codes like “404 – Not Found”, it doesn’t provide a status code page by default. When no response body is provided for a 400-599 HTTP error status code, the application returns the status code and an empty response body.

You can call the UseStatusCodePages method in your application’s Program.cs file to enable text-only handlers for common error status codes. You can use the StatusCodePagesMiddleware class in ASP.NET Core to generate the response as shown in the code snippet below.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseStatusCodePages(async statusCodeContext
    => await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode)
                 .ExecuteAsync(statusCodeContext.HttpContext));
app.Map("/authors/{id:int}", (int id)
    => id <= 0 ? Results.BadRequest() : Results.Ok(new Author(id)));
app.Run();
public record Author(int Id);

In ASP.NET Core apps, exception filters can be used to catch specific types of exceptions and handle them appropriately. To use a filter, implement the IExceptionFilter interface and add it to the application pipeline. You can learn more about using exception filters (and other filters) in ASP.NET Core in my previous article here.

Copyright © 2023 IDG Communications, Inc.

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *