简体   繁体   中英

Custom Middleware doesn't handle exception with debug run ASP.NET CORE

I am trying to use middleware for exception handling in my ASP.Net Core 5.0 project but it doesn't handle the exception and debugging stops the application when exception is thrown.

    
public class CustomExceptionMiddleWare
    {
        private readonly RequestDelegate _next;
        public CustomExceptionMiddleWare(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            var watch = Stopwatch.StartNew();
            try
            {
                string message = "[Request] HTTP " + context.Request.Method + " - " + context.Request.Path;
                Console.WriteLine(message);
                await _next(context);
                watch.Stop();
                message = "[Request] HTTP " + context.Request.Method + " - " + context.Request.Path + " responded " +
                    context.Response.StatusCode.ToString() + " in " + watch.Elapsed.TotalMilliseconds + " ms";
                Console.WriteLine(message);
            }
            catch (Exception ex)
            {
                watch.Stop();
                await HandleException(context, ex, watch);
            }
        }

        private Task HandleException(HttpContext context, Exception ex, Stopwatch watch)
        {
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;


            string message = "[Error]   HTTP" + context.Request.Method + " - " + context.Response.StatusCode +
                " Error Message " + ex.Message + " in " + watch.Elapsed.TotalMilliseconds + " ms";
            Console.WriteLine(message);


            var result = JsonConvert.SerializeObject(new { Error = ex.Message }, Formatting.None);
            return context.Response.WriteAsync(result);
        }
    }


    public static class CustomExceptionMiddlewareExtension
    {
        public static IApplicationBuilder UseCustomExceptionMiddleWare(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<CustomExceptionMiddleWare>();
        }
    }
}

startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                //app.UseDeveloperExceptionPage();
                app.UseCustomExceptionMiddleWare();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "PatikaWebApi v1"));

            }

            
            //app.UseMiddleware<CustomExceptionMiddleWare>();
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseCustomExceptionMiddleWare();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

controller

 [HttpGet("{id}")]
        public IActionResult GetById(int id)
        {
            BookDetailViewModel result;
            GetBooksDetailQuery query = new GetBooksDetailQuery(_context,_mapper);
            query.BookId = id;
            GetBooksDetailQueryValidator validator = new GetBooksDetailQueryValidator();
            validator.ValidateAndThrow(query);
            result = query.Handle();
            return Ok(result);        
        }

When the exception is thrown middleware doesn't handle the exception with Debug mode. I searched for the solution and i found one that removing app.UseDeveloperExceptionPage(); row didn't work for me.I have tried to change pipeline but didn't work either. What would be the solution? Thank you for your attention.

Error is Exception User-Unhandled

on the surface I cannot see why your debug point is not being hit. But I would suggest using a filter instead of middleware for this scenario.

You can look at a article by Jason Taylor on how to do this. Here is his github source code link.

https://github.com/jasontaylordev/CleanArchitecture/blob/main/src/WebUI/Filters/ApiExceptionFilterAttribute.cs

I also wrote a simplified example for you. I hope this fixes your problem.

Exception filter:

using Microsoft.AspNetCore.Mvc.Filters;

namespace Multitrust.API.Filters
{
public class ApiExceptionFilter : ExceptionFilterAttribute
{
    public ApiExceptionFilter() 
    {
    }


    public override void OnException(ExceptionContext context)
    {

        HandleException(context);
    }

    private void HandleException(ExceptionContext context)
    {
        //Do stuff with the exception
    }

    }
}

Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddControllersWithViews(options =>
            options.Filters.Add(new ApiExceptionFilter()));
            
      //Bind other services...

     }

Let me know if you need any help with this.

Happy coding

There is already a middleware provided in .NET core. app.UseExceptionHandler . you need to define the response when exception is raised.

I had written a simple article sometime back on same topic. have a look.

Handling exceptions in ASP.Net core API

hope it solves your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM