Why is IStatusCodeReExecuteFeature always null with a status code of 500?

Viewed 164

I am getting an unhandled exception in my ASP.NET Razor Pages application. My Error.cshtml page emails me the details, but doesn't (currently) include the query string. I need this to work out why the exception is happening.

I have the following code in Startup.cs to set up error handling (check for IsDevelopment removed for testing)...

    public async void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
      app.UseExceptionHandler("/Error");
      app.UseHttpsRedirection();
      app.UseStatusCodePagesWithReExecute("/Error", "?code={0}");
      // etc...
    }

The Error.cshtml.cs code contains code to get IExceptionHandlerPathFeature, which works fine. It also contains this code to get the query string...

IStatusCodeReExecuteFeature statusCodeReExecuteFeature =
    HttpContext.Features.Get<IStatusCodeReExecuteFeature>();

(code taken from MSDN)

When my code throws an unhandled exception, which generates an HTTP status code of 500, the code above returns null, so I can't get the query string.

According to the second comment on this question, CodePages works only for 4xx and 5xx errors. However, as I'm getting a 500 (which I can see in the browser dev tools), I don't understand why it's null.

Anyone able to explain why it's null, and how I can get the query string? Please let me know if there is anything more I can add to clarify.

1 Answers

I had the same problem, when using both UseExceptionHandler and UseStatusCodePagesWithReExecute on the same page/controller action you need to try both IStatusCodeReExecuteFeature and IExceptionHandlerPathFeature to support each use-case.

I use this method:

private string GetUrl()
{
    // Handles non-exception related Status Codes
    var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
    if (statusCodeReExecuteFeature != null) return statusCodeReExecuteFeature.OriginalPath;
    
    // Handles exception related status codes
    var exceptionHandlerPathFeature = Request.HttpContext.Features.Get<IExceptionHandlerPathFeature>();
    if (exceptionHandlerPathFeature != null) return exceptionHandlerPathFeature.Path;

    // Falls back to current url, probably something like /status/{code}
    return Request.GetDisplayUrl();
}
Related