Exceptions handling EF Core 2.0

.net-core c# entity-framework-core

Question

I'm using EF Core 2.0 with Repository and Unit of Work patterns. What is the best way to handle all db exceptions?. Can I just use try/catch in my commit method?

public void Commit()
{
    try
    {
        _context.SaveChanges();
    }
    catch (Exception ex)
    {
         //code
    }
}

Can anything beyond SaveChanges() throw an exception? What should do next with caught exception?

1
0
8/29/2018 8:13:21 AM

Popular Answer

I would give you an example how I would personally implement, maybe you can improve it as per your requirements but at least you have a good starting point.

  • First option (only for Asp.Net Core).

Create a middleware which will handle exceptions in general like below:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;

    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task Invoke(HttpContext context, ILogger logger)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        { 
            await HandleExceptionAsync(context, ex, logger);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception exception, ILogger logger) 
    {
        if(exception is DbException)
        {
            //Do something else if needed
        }
        logger.Log(exception);
        //do something
        return context.Response.WriteAsync(... something ...); //Maybe some JSON message or something
    }
}

Then register the middleware like below in configure method:

app.UseMiddleware<ErrorHandlingMiddleware>();

DbException might be just a custom exception you may throw or you can put other existing exceptions types in there if you want to handle them differently.

In case you are using ASP.NET MVC you can have a BaseController and use this here:

  • Second option I personally have used is by implementing unit of work like below.

    using (var unitOfWork = UnitOfWorkManager.NewUnitOfWork())
    {
        if (ModelState.IsValid)
        {
            //Do Stuff
            try
            {
                unitOfWork.Commit();
            }
            catch (Exception e)
            {
                unitOfWork.Rollback();
                LoggingService.LogCommitException(e);
            }
         }
     }
     

    The second option is sometimes more preferable if you want to include more business logic code when an exception happened.

In your case go with second option but you may include both options in the solution as middleware can catch other global exceptions as well.

I would suggest to not include any try-catch inside commit method because it is not it's responsibility to catch any exceptions, further more you would have to inject a logger inside of UnitOfWork manager which can be emitted. So, to conclude commit method has only to commit, other actions should be outside of its scope.

0
8/29/2018 11:18:39 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow