This article outlines how I handle errors in Umbraco 10.

What I have done is create a CustomError Document type, following the Umbraco docs for a custom 404 page, using the same template I created some more error pages, an errorNoAcess and errorHandler. The CustomError Document type just basic template with a title and message.

I discovered that depending how the error is raised/returned, you could get either an exception or a http statuscode, so you have to handle both :)

So, I created my own exceptionhandler midddleware to handle the exceptions and then added some code to my startup.cs to handle the status codes.

using System.Net;
using Microsoft.AspNetCore.Http;

namespace MediaWiz.Core.MiddleWare
{
    public class ExceptionHandlingMiddleware
    {
        private readonly RequestDelegate _next;

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

        public async Task InvokeAsync(HttpContext context)
        {
            var allowedcodes = new[] { 200, 301, 302, 401,403,404,500 };
            try
            {
                await _next(context);
                if (!allowedcodes.Contains(context.Response.StatusCode))
                {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.Response.Redirect("/errorHandler");

                }
            }
            catch (UnauthorizedAccessException)
            {
                context.Response.Clear();
                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                context.Response.Redirect("/errorNoAccess");
            }
            catch (Exception ex)
            {
                if (context.Response.StatusCode is 404)
                {
                    //may be from an exception in startup, so lets just let it get handled by the default 404;
                }
                else
                {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.Response.Redirect("/errorHandler");
                }

            }
        }
    }
}

I also added an extension method to register the middleware.

public static class MiddleWareExtensions
{
    public static IApplicationBuilder MyExceptionHandler(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<ExceptionHandlingMiddleware>();
    }
}

 

I then registered it in my startup.cs and added some code to handle errors returned as statuscodes in the response

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IBackgroundJobClient backgroundJobClient, IRecurringJobManager recurringJobManager)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.MyExceptionHandler();
            }

            app.Use(async (context, next) =>
            {
                context.Response.Headers.Add("X-Xss-Protection", "1; mode=block");
                context.Response.Headers.Add("Strict-Transport-Security", "max-age=31536000");
                context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
                context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
                await next();

                if (context.Response.StatusCode == 404)
                {
                    context.Request.Path = "/error404/";
                    await next();
                }
                if (context.Response.StatusCode is 401 or 403)
                {
                    context.Request.Path = "/errorNoAccess/";
                    await next();
                }
                //This is a BadRequest so use the default handler (500)
                if (context.Response.StatusCode == 500)
                {
                    context.Request.Path = "/errorHandler/";
                    await next();
                }
            });

            app.UseAuthentication();
            app.UseRouting();

            app.UseUmbraco()
                .WithMiddleware(u =>
                {
                    u.UseBackOffice();
                    u.UseWebsite();
                })
                .WithEndpoints(u =>
                {
                    u.UseInstallerEndpoints();
                    u.UseBackOfficeEndpoints();
                    u.UseWebsiteEndpoints();
                });

        }

 

In this article I will explain how to configure the TinyMCE rich text editor in Umbraco v14

This is my dive into the new Umbraco 14 backoffice to create a Member EntityAction in order to send an email to the selected member.

Previously known as Tree Actions, Entity Actions is a feature that provides a generic place for secondary or additional functionality for an entity type. An entity type can be a media, document and so on.

In this blog post I explain how to implement an email validation flow for Member registration.