1

Almost all exceptions are getting caught except the exception from EF core . The exception filter is catching any error . but not errors from entity framework. If you need any other info like efcore model etc i can provide it , but it will become a long one .

This is my Exception filter

public class CustomExceptionFilter : ExceptionFilterAttribute
    {
        public override void OnException(ExceptionContext context)
        {
            Exception ex = context.Exception;
            if (context.Exception is IndexOutOfRangeException)
                context.Result = new OkObjectResult(new { error = true, errorMessage = ex.Message });
            else if (context.Exception is ArgumentOutOfRangeException)
                context.Result = new OkObjectResult(new { error = true, errorMessage = ex.Message });
            else if(context.Exception is AggregateException)
                context.Result = new OkObjectResult(new { error = true, errorMessage = ex.Message });
       }
}

This the configure Services method

  public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers(options=> {
                options.Filters.Add<ProductTypeSeedFilter>();
                options.Filters.Add<CustomExceptionFilter>();
                options.Filters.Add<VehicleSeedFilter>();
                });
            services.AddDbContext<InventoryContext>(options =>
                options.UseSqlServer (Configuration.GetConnectionString( "DefaultConnection")),ServiceLifetime.Transient
            );

            services.AddSingleton<IProductService, ProductService>();
            services.AddSingleton<IVehicleService, VehicleService>();
            services.AddTransient<IVehicleRepository, VehicleRepository>();
            services.AddTransient<IProductRepository, ProductRepository>();

            services.AddMvc(o => { o.Filters.Add<CustomExceptionFilter>(); });

            services.AddControllers().AddJsonOptions(options =>
                options.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.Preserve
            );
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "InventoryAPI2", Version = "v1" });
            });
        }

this is the repository method.I am trying to generate an error by inserting existing EAN for Product ean .


        public async Task<int> InsertProduct(ProductDTO productDTO)
        {
            Product p = new Product()
            {
                EAN = productDTO.EAN,
                Description = productDTO.Description,
                MinimumRetail = productDTO.MinimumRetail,
                MultipackUnits = productDTO.MultipackUnits,
                Packsize = productDTO.PackSize,
                QtyOnHand = productDTO.QtyOnHand,
                RetailPrice = productDTO.RetailPrice,
                CreatedDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                HubNo = productDTO.Store,
                tableKey = productDTO.datakey,
                Store = _dbcontext.Stores.Where(x => x.HubNo == productDTO.Store).FirstOrDefault()
            };
            _dbcontext.Products.Add(p);
            //if (_dbcontext.Products.Where(x => x.EAN == p.EAN).Count() < 1)
            //    _dbcontext.Products.Add(p);
            await _dbcontext.SaveChangesAsync();

            return _dbcontext.Products.Count();

        }

this is the controller Action Method .

 [HttpPost]
 [CustomExceptionFilter]
 public IActionResult Post([FromBody] ProductDTO productDTO)
 {
     return Ok( new { cnt =_productRepository.InsertProduct(productDTO) });
 }

Can any one help me here ?

5
  • EANis your primary key for Product? Commented Nov 13, 2023 at 8:49
  • First of all, apart of your CustomExceptionFilter do you have built-in logging in ASP.NET Core to Log the exception to get more information about what kind of exception is being thrown. Another importnant point is that, ensure that the order of execution of your exception filter is correct. Filters are executed in the order they are added to the filter pipeline. Make sure that your CustomExceptionFilter is registered early in the pipeline. Commented Nov 13, 2023 at 9:05
  • Oh one more thing, please double check, exception thrown by Entity Framework Core is of the expected type that your CustomExceptionFilter is looking for. EF Core might throw exceptions that are not directly derived from Exception. You might need to check for more specific types Commented Nov 13, 2023 at 9:05
  • @DenisMicheal . Sorry for the delayed response . Yes EAN , Store is the primary Key for the product . Commented Nov 25, 2023 at 8:25
  • @MdFaridUddinKiron The Debug pointer never Reaches the OnException method . Commented Nov 25, 2023 at 8:51

1 Answer 1

0

In your Exception Filter you aren't accounting for the exception type DbUpdateException

Exception thrown by DbContext when the saving of changes to the database fails. Note that state entries referenced by this exception are not serialized due to security and accesses to the state entries after serialization will return null.

i.e Add this in part of your conditions:

else if (context.Exception is DbUpdateException)
    context.Result = new OkObjectResult(new { error = true, errorMessage = ex.Message });

Supplementary

You could change your conditional statements to a switch rather than having multiple else if's much readable and neater :)

 var ex = context.Exception;
 var errorResponse = new { error = true, errorMessage = ex.Message };

 switch (context.Exception)
 {
     case IndexOutOfRangeException:
     case ArgumentOutOfRangeException:
     case AggregateException:
     case DbUpdateException:
     default:
         context.Result = new OkObjectResult(errorResponse);
         break;
 }

Your condition also did not have an else to handle the rest of the exceptions.(Included the default to handle the rest of the exceptions that can occur)

with pattern matching above switch can be improved to:

 var ex = context.Exception;
 var errorResponse = new { error = true, errorMessage = ex.Message };

 context.Result = ex switch
 {
     IndexOutOfRangeException or
     ArgumentOutOfRangeException or
     AggregateException or
     DbUpdateException or _ => new OkObjectResult(errorResponse),
 };
Sign up to request clarification or add additional context in comments.

2 Comments

I applied this answer , the debug pointer never reaches the OnException Method . I cant figure out how to start solving this .
As long as attribute [CustomExceptionFilter] is added to controller or controller method, when an exception occurs on that route and it's not caught in controller this method will be excuted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.