Custom error pages not working in Azure web apps
# help-with-umbraco
s
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:
Copy code
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
a
That sounds quite odd tbh
Im currently vigerously trying to brake my site to see if I have the same 😄
c
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. @skttl
s
@CodeSharePaul 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.
a
@skttl 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
s
weird - I need to try a fresh project 🙂
a
For local testing, do remove the app.UseDeveloperExceptionPage();
else you still get the dev error
s
@Ambert how are you going to your surface controller? Just tried a fresh new project, surface controller is:
Copy code
cs
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:
Copy code
cs
@{
    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
a
I just went to the surface controller Url
not specifcally get/set
s
Sorry, just had to update the get tester, to actually do a get request with
Copy code
@using (Html.BeginUmbracoForm<TestSurfaceController>("TestGet", FormMethod.Get))
{
    <button>Get</button>
}
This works now... So I'm down to the post request 🙂
a
So.. All good now ? 😄
s
Almost - just need to get i firing after a POST request 🙂
d
Is it even possible to serve a static file with a post request? Could you try requesting 500.html with a post request directly?
s
@D_Inventor you are right - is because it's preventing the post request to the static file
d
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:
Copy code
csharp
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.
c
3 Views