Middleware e tratamento de exceções

Eu sou novo no conceito de middleware e atualmente estou tendo dificuldades com a maneira correta de lidar com exceções no meu projeto MVC Core.

O que eu quero que aconteça é que a exceção seja capturada, registrada e, em seguida, envie o usuário para uma página de erro amigável com uma mensagem. No começo, eu estava tentando gerenciar tudo isso no middleware, mas percebi que provavelmente não estava fazendo isso corretamente.

Portanto, se eu quiser que esse fluxo ocorra, devo usar o middleware de log de exceção E o app.UseExceptionHandler ("/ Error") para que o middleware volte a lançar a exceção na página? E se sim, como obtenho os detalhes da exceção na página Erro? E é correto que o mecanismo de tratamento de exceções que desejo interceptar primeiro seja o último no Configure?

Todos os exemplos que encontrei lidam estritamente com erros do código de status HTTP como 404; Eu estou olhando para lidar com exceções reais (e suas subclasses). Dessa forma, nas minhas páginas do View, posso lançar minhas próprias exceções, quando aplicável (por exemplo, se um View for nulo para um campo obrigatório).

Snippet Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
                      ILoggerFactory loggerFactory, LoanDbContext context) {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
   , loggerFactory.AddDebug();

    app.UseStatusCodePages();
    if (env.IsDevelopment() || env.IsEnvironment("qa")) {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    } else {
        app.UseExceptionHandler("/Error");
    }
    app.UseMiddleware<MyExceptionHandler>(loggerFactory);
    // ... rest of Configure is irrelevant to this issue

MyExceptionHandler.cs

using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace MyCompany.MyProject.Helpers
{
    /// <summary>
    /// A custom Exception Handler Middleware which can be re-used in other projects.
    /// </summary>
    public sealed class MyExceptionHandler
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        public MyExceptionHandler(RequestDelegate next, ILoggerFactory loggerFactory) {
            _next = next;
            _logger = loggerFactory.CreateLogger<MyExceptionHandler>();
        }

        public async Task Invoke(HttpContext context) {
            try {
                await _next(context);
            } catch (Exception ex) {
                HandleException(ex);
            }
        }

        // I realize this function looks pointless, but it will have more meat to it eventually.
        public void HandleException(Exception ex) {
            if (ex is ArgumentException argEx) {
                _logger.LogError(0, argEx, argEx.Message);
            } else if (ex is InvalidOperationException ioEx) {
                _logger.LogError(0, ioEx, "An Invalid Operation Exception occurred. This is usually caused by a database call that expects "
                    + "one result, but receives none or more than one.");
            } else if (ex is SqlException sqlEx) {
                _logger.LogError(0, sqlEx, $"A SQL database exception occurred. Error Number {sqlEx.Number}");
            } else if (ex is NullReferenceException nullEx) {
                _logger.LogError(0, nullEx, $"A Null Reference Exception occurred. Source: {nullEx.Source}.");
            } else if (ex is DbUpdateConcurrencyException dbEx) {
                _logger.LogError(0, dbEx, "A database error occurred while trying to update your item. This is usually due to someone else modifying the item since you loaded it.");
            } else {
                _logger.LogError(0, ex, "An unhandled exception has occurred.")
            }
        }
    }
}