Skip to content

RequestDelegateFactory should throw BadHttpRequestException when in development to make diagnosing handler issues easier #35858

Closed
@DamianEdwards

Description

@DamianEdwards

When using the new "Map*" methods to build minimal APIs via the RouteDelegateFactory, it can be difficult to diagnose the cause of 400 and 415 responses that are implicitly returned when the mapped route handler's parameters cannot be satisfied from the request, either via the implicit parameter binding behavior or TryParse' and 'BindAsync methods on the parameter target types.

It would be helpful if when in development (i.e. Environment.IsDevelopment() == true) instead of implicitly returning the response with a 4xx status code, a BadHttpRequestException was thrown instead, with the relevant status code set and an appropriate exception message added, making it clear why the exception/status code is being throw/set. With the DeveloperExceptionPageMiddleware on (which it is by default in development in .NET 6 when using WebApplication) the exception message and stack trace will be returned in the response body, making it much clearer why the invocation of the route handler failed.

This behavior should be controllable via a new options type RouteHandlerOptions with boolean property ThrowOnBadRequest that is configured by default to be true when Environment.IsDevelopmet() is true. The default configuration would be achieved via an internal type implementing IConfigureOptions<RouteHandlerOptions> that is registered in DI when IServiceCollection.AddRouting() is called.

Related:

Proposed APIs

namespace Microsoft.AspNetCore.Routing
{
+    public class RouteHandlerOptions
+    {
+        public bool ThrowOnBadRequest { get; set; }
+    }
}

namespace Microsoft.AspNetCore.Http
{
    public class RequestDelegateFactoryOptions
    {
+        public bool ThrowOnBadRequest { get; init; }
    }
}

Example usage

var builder = WebApplication.CreateBuilder(args);

// Enable exceptions for implicit 4xx responses in custom "LocalDev" environment
var isDev = app.Environment.IsDevelopment() || app.Environment.IsEnvironemnt("LocalDev");
builder.Services.Configure<RouteHandlerOptions>(options => options.ThrowOnBadRequest = isDev);

var app = builder.Build();

Metadata

Metadata

Assignees

Labels

Priority:1Work that is critical for the release, but we could probably ship withoutapi-approvedAPI was approved in API review, it can be implementedarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-minimal-actionsController-like actions for endpoint routingold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions