#Custom error pages not working in Azure web apps

1 messages ยท Page 1 of 1 (latest)

lunar kestrel
#

I'm trying to set up a custom error page (just a static 500.html page) using app.UseExceptionHandler("/500.html");. It works as expected when working locally (in env.IsDevelopment()), but when deployed to an Azure Web App, I still get til empty default browser error page. Anyone tried this, and have some pointers? It's Umbraco 12. There is nothing in web.config taking over either.

I have this as the first part of the Configure method in Startup.cs:

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/500.html");
            app.Use(async (context, next) =>
            {
                // Detect and work around issue causing the error page not to be displayed:
                if (context.Response.StatusCode == StatusCodes.Status500InternalServerError && context.Request.Path == "/500.html")
                {
                    context.Features.Set<UmbracoRouteValues>(instance: null);
                }
                await next();
            });
        }
#

Okay, it's actually not working in local either. It works, if it's a error in a view, but if there is an error in eg. a SurfaceController action, it doesn't

austere creek
#

That sounds quite odd tbh

#

Im currently vigerously trying to brake my site to see if I have the same ๐Ÿ˜„

simple glen
#

Sorry to patronise you but do you have the 500.html page in the wwwroot folder, with it being a static file and needing to be served from there. @lunar kestrel

lunar kestrel
#

@simple glen no offence taken ๐Ÿ™‚ Yes, I have the file in wwwroot. It also works if its an exception thrown from eg. a view. But when the exception is thrown from a surface controller (specifically on a post request) it doesn't show.

austere creek
#

@lunar kestrel Just tested this locally
I've made a fresh project, made a view, typed in throw new ArgumentOutOfRangeException("Error", "ThisIsAnError."); and added the 500 file in wwwroot and added the `app.UseExpectionHandler("/500.html")
Getting the nice error

Added a simple SurfaceController with the same throw in it
Getting the nice error

lunar kestrel
#

weird - I need to try a fresh project ๐Ÿ™‚

austere creek
#

For local testing, do remove the app.UseDeveloperExceptionPage();

#

else you still get the dev error

lunar kestrel
#

@austere creek how are you going to your surface controller?

Just tried a fresh new project, surface controller is:

public class TestSurfaceController : SurfaceController
{
    public TestSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
    {
    }

    [HttpGet]
    public IActionResult TestGet()
    {
        throw new Exception("Test");
    }

    [HttpPost]
    public IActionResult TestPost()
    {
        throw new Exception("Test");
    }
}

Then I have my home page view:

@{
    Layout = null;
    if (Context.Request.Query["throw"] == "ex")
    {
        throw new Exception("throw==ex");
    }
}

@using (Html.BeginUmbracoForm<TestSurfaceController>("TestGet"))
{
    <button>Get</button>
}

@using (Html.BeginUmbracoForm<TestSurfaceController>("TestPost"))
{
    <button>Get</button>
}

<a href="/?throw=ex">throw from view</a>

Clicking the throw from view link gets me my custom error page. None of the forms does

austere creek
#

I just went to the surface controller Url

#

not specifcally get/set

lunar kestrel
#

Sorry, just had to update the get tester, to actually do a get request with

@using (Html.BeginUmbracoForm<TestSurfaceController>("TestGet", FormMethod.Get))
{
    <button>Get</button>
}

This works now... So I'm down to the post request ๐Ÿ™‚

austere creek
#

So.. All good now ? ๐Ÿ˜„

lunar kestrel
#

Almost - just need to get i firing after a POST request ๐Ÿ™‚

olive jasper
#

Is it even possible to serve a static file with a post request? Could you try requesting 500.html with a post request directly?

lunar kestrel
#

@olive jasper you are right - is because it's preventing the post request to the static file

olive jasper
#

Then I think you need a middleware that checks if you're doing a re-entry in the pipeline due to an exception and change the httpverb in the httpcontext into GET. I might have an example for the first half

#

This example class uses the exception handler feature to check if the current request has performed a re-entry:

public class ServerErrorResponseCodeMiddleware
{
    private readonly RequestDelegate _next;

    public ServerErrorResponseCodeMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task InvokeAsync(HttpContext context)
    {
        context.Response.OnStarting(() =>
        {
            var exceptionPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();

            if (exceptionPathFeature is not null)
            {
                context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            }

            return Task.CompletedTask;
        });

        return _next(context);
    }
}

In your case you omit context.Response.OnStarting and instead perform your logic immediately.