Skip to content

Commit

Permalink
Fixed Missing Endpoint (#5135)
Browse files Browse the repository at this point in the history
Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com>
  • Loading branch information
cliedeman and alanwest authored Jan 27, 2024
1 parent 3fb2ec5 commit 26a2d4b
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http;
#if !NETSTANDARD
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Routing;
#endif
using OpenTelemetry.Context.Propagation;
Expand Down Expand Up @@ -231,7 +232,8 @@ public void OnStopActivity(Activity activity, object payload)
var response = context.Response;

#if !NETSTANDARD
var routePattern = (context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText;
var routePattern = (context.Features.Get<IExceptionHandlerPathFeature>()?.Endpoint as RouteEndpoint ??
context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText;
if (!string.IsNullOrEmpty(routePattern))
{
activity.DisplayName = GetDisplayName(context.Request.Method, routePattern);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#if NET6_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Routing;
#endif
using OpenTelemetry.Trace;
Expand Down Expand Up @@ -86,7 +87,9 @@ public static void OnStopEventWritten(string name, object payload)
tags.Add(new KeyValuePair<string, object>(SemanticConventions.AttributeHttpRequestMethod, httpMethod));

#if NET6_0_OR_GREATER
var route = (context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText;
// Check the exception handler feature first in case the endpoint was overwritten
var route = (context.Features.Get<IExceptionHandlerPathFeature>()?.Endpoint as RouteEndpoint ??
context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText;
if (!string.IsNullOrEmpty(route))
{
tags.Add(new KeyValuePair<string, object>(SemanticConventions.AttributeHttpRoute, route));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
| :green_heart: | RazorPages | [Static content](#razorpages-static-content) |
| :green_heart: | MinimalApi | [Action without parameter](#minimalapi-action-without-parameter) |
| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) |
| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) |

## ConventionalRouting: Root path

Expand Down Expand Up @@ -590,3 +591,22 @@
}
}
```

## ExceptionMiddleware: Exception Handled by Exception Handler Middleware

```json
{
"IdealHttpRoute": "/Exception",
"ActivityDisplayName": "GET /Exception",
"ActivityHttpRoute": "/Exception",
"MetricHttpRoute": "/Exception",
"RouteInfo": {
"HttpMethod": "GET",
"Path": "/Exception",
"RoutePattern.RawText": null,
"IRouteDiagnosticsMetadata.Route": null,
"HttpContext.GetRouteData()": {},
"ActionDescriptor": null
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) |
| :green_heart: | MinimalApi | [Action without parameter (MapGroup)](#minimalapi-action-without-parameter-mapgroup) |
| :green_heart: | MinimalApi | [Action with parameter (MapGroup)](#minimalapi-action-with-parameter-mapgroup) |
| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) |

## ConventionalRouting: Root path

Expand Down Expand Up @@ -632,3 +633,22 @@
}
}
```

## ExceptionMiddleware: Exception Handled by Exception Handler Middleware

```json
{
"IdealHttpRoute": "/Exception",
"ActivityDisplayName": "GET /Exception",
"ActivityHttpRoute": "/Exception",
"MetricHttpRoute": "/Exception",
"RouteInfo": {
"HttpMethod": "GET",
"Path": "/Exception",
"RoutePattern.RawText": null,
"IRouteDiagnosticsMetadata.Route": null,
"HttpContext.GetRouteData()": {},
"ActionDescriptor": null
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,14 @@
"expectedStatusCode": 200,
"currentHttpRoute": null,
"expectedHttpRoute": "/MinimalApiUsingMapGroup/{id}"
},
{
"name": "Exception Handled by Exception Handler Middleware",
"testApplicationScenario": "ExceptionMiddleware",
"httpMethod": "GET",
"path": "/Exception",
"expectedStatusCode": 500,
"currentHttpRoute": null,
"expectedHttpRoute": "/Exception"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using System.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
Expand Down Expand Up @@ -33,6 +34,11 @@ public enum TestApplicationScenario
/// An Razor Pages application.
/// </summary>
RazorPages,

/// <summary>
/// Application with Exception Handling Middleware.
/// </summary>
ExceptionMiddleware,
}

internal class TestApplicationFactory
Expand All @@ -53,6 +59,8 @@ internal class TestApplicationFactory
return CreateMinimalApiApplication();
case TestApplicationScenario.RazorPages:
return CreateRazorPagesApplication();
case TestApplicationScenario.ExceptionMiddleware:
return CreateExceptionHandlerApplication();
default:
throw new ArgumentException($"Invalid {nameof(TestApplicationScenario)}");
}
Expand Down Expand Up @@ -154,4 +162,38 @@ private static WebApplication CreateRazorPagesApplication()

return app;
}

private static WebApplication CreateExceptionHandlerApplication()
{
var builder = WebApplication.CreateBuilder();
builder.Logging.ClearProviders();

var app = builder.Build();

app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
await context.Response.WriteAsync(exceptionHandlerPathFeature?.Error.Message ?? "An exception was thrown.");
});
});

app.Urls.Clear();
app.Urls.Add("http://[::1]:0");

// TODO: Remove this condition once ASP.NET Core 8.0.2.
// Currently, .NET 8 has a different behavior than .NET 6 and 7.
// This is because ASP.NET Core 8+ has native metric instrumentation.
// When ASP.NET Core 8.0.2 is released then its behavior will align with .NET 6/7.
// See: https://github.com/dotnet/aspnetcore/issues/52648#issuecomment-1853432776
#if !NET8_0_OR_GREATER
app.MapGet("/Exception", (ctx) => throw new ApplicationException());
#else
app.MapGet("/Exception", () => Results.Content(content: "Error", contentType: null, contentEncoding: null, statusCode: 500));
#endif

return app;
}
}

0 comments on commit 26a2d4b

Please sign in to comment.