Search code examples
c#asp.net-coreexceptionrazor

ASP.NET Core Razor - Global Exception Handler


I have the following which partially works in the .cshtml.cs but not the .cshtml file:

Do I need to change my GlobalExceptionFilter or do I need to add something else to catch the .cshtml errors?

For both of the errors they do redirect to the /Error page.

public class GlobalExceptionFilter : IExceptionFilter
{       
    public void OnException(ExceptionContext context)
    {
        LogError(context.Exception);
    }
}

In Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcOptions(options =>
                {
                    options.Filters.Add<GlobalExceptionFilter>();
                });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
        }
}

In Index.cshtml.cs:

public void OnGet()
{
    throw new Exception("Test"); //This hits GlobalExceptionFilter
}

In Index.cshtml:

@{
    throw new Exception("Test"); //This does NOT hit GlobalExceptionFilter
}

Thanks in advance


Solution

  • From the doc:

    Exception filters apply global policies to unhandled exceptions that occur before the response body has been written to.

    Exception filters:

    Are good for trapping exceptions that occur within actions.

    Are not as flexible as error handling middleware.

    Here you can use a custom ExceptionHandler middleware like below:

    public class CustomExceptionHandler
    {
        private readonly IWebHostEnvironment _environment;
        
        public CustomExceptionHandler(IWebHostEnvironment environment)
        {
            _environment = environment;
        }
    
        public async Task Invoke(HttpContext httpContext)
        {
                var feature = httpContext.Features.Get<Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature>();
                var error = feature?.Error;
    
                if(error != null)
                {                    
                    LogError(error);
                    throw error;
                }
    
                await Task.CompletedTask;
        }
    }
    

    Use it in the startup.cs

    app.UseExceptionHandler(new ExceptionHandlerOptions
    {
        ExceptionHandler = new CustomExceptionHandler(env).Invoke
    });