Wie erstelle ich Fehlerseiten für Umbraco 10

Seit Version 9 basiert Umbraco auf ASP.Net Core und seit Version 10 auf .Net 6. Dadurch haben sich einige Änderungen in der  Infrastruktur ergeben.
Dazu gehören auch die Fehlerseiten (z.B. 500 interner Serverfehler), wenn mal etwas nicht wie gedacht funktioniert.

Für die häufigsten 404-Fehler (Seite nicht gefunden) bringt Umbraco eine rudimentäre Konfigurationslösung Error404Collection mit:

"Umbraco": {
    "CMS": {
        "Runtime": {...},
        "Global": {...},
        "ModelsBuilder": {...},
        "Content": {
            "Error404Collection": [
                {
                    "Culture": "default",
                    "ContentKey": "5baec761-98cf-42ff-8540-1c87dc06cbbc"
                }
            ],
            ...

Hier gibt es die Möglichkeit eine bereits veröffentlichte Seite über ihre Id, GUID (key) oder einen XPath-Ausdruck pro Culture zu definieren.

Andere Fehler wie zum Beispiel 500 interner Serverfehler, die zur Laufzeit auftreten können, erfordern etwas mehr Aufwand. Die Dokumentation auf our.umbraco.com verweist aktuell nur auf die Microsoft Dokumentation, die allerdings nur ein paar grundsätzliche Hinweise gibt.

Meine einfache Lösung besteht aus folgenden Schritten:

  1. Anlegen eines MVC ~\Controllers\ErrorControllers.cs im Umbraco.Web-Projekt:
    using Microsoft.AspNetCore.Mvc;
    
    namespace UmbracoProject.Web.Controllers
    {
        public class ErrorController : Controller
        {
            [Route("Error")]
            public IActionResult Index()
            {
                if (Response.StatusCode != StatusCodes.Status200OK)
                {
                    var exceptionHandlerPathFeature =
                        HttpContext.Features.Get();
                    var path = exceptionHandlerPathFeature?.Path ?? string.Empty;
                    if (path.StartsWith("/statuscodes"))
                    {
                        //Hier wird ein Standard-MVC-View angezeigt, den man nicht über das CMS Back-Office pflegen kann.
                        return View();
                    }
    
                    if (Response.StatusCode == StatusCodes.Status500InternalServerError)
                    {
                        return Redirect("/statuscodes/500");
                    }
    
                    return Redirect("/statuscodes");
                }
    
                return Redirect("/");
            }
        }
    }
    
  2. Eine View-Datei unter dem üblichen MVC-Pfad ~/Views/Error/Index.cshtml anlegen. Diese sollte möglichst keine fehleranfällige Logik oder unnötige Abhängigkeiten enthalten. Sie dient nur als letzte Möglichkeit eine gestaltete Rückmeldung für den Benutzer anzuzeigen.
  3. Zulassen der neuen Route "Error" in den ReservedPaths in der Datei appSettings.json:
    "Umbraco": {
        "CMS": {
            "Global": {
                "ReservedPaths": "~/app_plugins/,~/install/,~/mini-profiler-resources/,~/umbraco/,~/error/",
                ...
    
  4. Anlegen der in Schritt 1. Redirect-Zielseiten als ganz normale Inhaltsseiten, die nicht in der Navigation oder Sitemap auftauchen. In diesem Beispiel die Seite "Statuscodes" mit einer Unterseite "500".
  5. Erweitern der Configure-Methode in der ~/Startup.cs Datei:
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/error");
        }
    
        ...
    }
    

Die Methode aus Schritt 1. ist sehr rudimentäre und verwendet hart kodierte Pfade. Eine schnelle Verbesserung könnte man durch eine entsprechende Konfiguration in appSettings.json erreichen. Noch besser wäre eine Möglichkeit die entsprechenden Fehlerseiten im Back-Office konfigurierbar zu machen. Allerdings hat der ErrorController keinen direkten Zugriff auf den Umbraco-Kontext.