Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Question for .NET Entity Framework Developers

Options
  • 11-10-2019 12:56pm
    #1
    Registered Users Posts: 444 ✭✭


    I’m a hobbyist programmer and have done some development as part of my job too.

    I’m developing a personal project using ASP.NET MVC with Entity Framework and a Service Layer in between.

    My question concerns error handling in the Data Access layer. It seems like overkill to wrap every method in a Try…Catch. This is particularly the case because I don’t need any recovery/retry steps in the Catch block. If a db error occurs, I’d simply want the except written to a log file and a message displayed on the front end.

    So, I could pass the exception back up to the caller in the Service Layer. The problem with that would be that it would expose data access implementation to the Service Layer which seems to be a big no no.

    When you are developing an Entity Framework data access layer, where do you handle exceptions (especially when the only operation in the Catch block is simply logging)?

    Thanks very much


Comments

  • Registered Users Posts: 17,501 ✭✭✭✭Mr. CooL ICE


    First thing that springs to mind would be to create an enum with internal messages indicating success/failure or whatnot and use them as the return value when the web layer makes calls to the service layer. Then the web layer can use Model.AddModelError if the return value != ErrorEnum.Success, or something like that.


  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    RickBlaine wrote: »
    I’m a hobbyist programmer and have done some development as part of my job too.

    I’m developing a personal project using ASP.NET MVC with Entity Framework and a Service Layer in between.

    My question concerns error handling in the Data Access layer. It seems like overkill to wrap every method in a Try…Catch. This is particularly the case because I don’t need any recovery/retry steps in the Catch block. If a db error occurs, I’d simply want the except written to a log file and a message displayed on the front end.

    So, I could pass the exception back up to the caller in the Service Layer. The problem with that would be that it would expose data access implementation to the Service Layer which seems to be a big no no.

    When you are developing an Entity Framework data access layer, where do you handle exceptions (especially when the only operation in the Catch block is simply logging)?

    Thanks very much

    If you're looking to do it properly then you'd have a data access layer with repositories that looks after data access using EF and mapping it to application models. Your service layer and MVC layer only work with the application models.

    You should avoid try/catch and allow the exception to bubble up. Deal with it in the global error handler that you have. If you don't get have one then there are a number of ways to do it. Stackoverflow will give you the examples you need.


  • Registered Users Posts: 444 ✭✭RickBlaine


    John_Mc wrote: »
    If you're looking to do it properly then you'd have a data access layer with repositories that looks after data access using EF and mapping it to application models. Your service layer and MVC layer only work with the application models.

    You should avoid try/catch and allow the exception to bubble up. Deal with it in the global error handler that you have. If you don't get have one then there are a number of ways to do it. Stackoverflow will give you the examples you need.

    Sorry, I didn't mention in my OP that I do actually return application modals from the data access layer and the service and MVC layers work with those.

    I've also read opinions online that exceptions should be handled as close as possible to where they are raised, which would suggest data access exceptions should not be handled in other layers. I guess there are differing opinions.

    I am happy to let SQL exceptions bubble up out of the data access layer and handled elsewhere as long as that is considered at least one proper way of doing things.


  • Moderators, Business & Finance Moderators Posts: 10,001 Mod ✭✭✭✭Jim2007


    First thing that springs to mind would be to create an enum with internal messages indicating success/failure or whatnot and use them as the return value when the web layer makes calls to the service layer. Then the web layer can use Model.AddModelError if the return value != ErrorEnum.Success, or something like that.

    This is overkill and leads to horrible code as ever other line starts an if bock, even if it is unnecessary.


  • Moderators, Business & Finance Moderators Posts: 10,001 Mod ✭✭✭✭Jim2007


    John_Mc wrote: »
    You should avoid try/catch and allow the exception to bubble up. Deal with it in the global error handler that you have. If you don't get have one then there are a number of ways to do it. Stackoverflow will give you the examples you need.

    Horrible code to have to maintain!

    OP, catch the exceptions you wish to handle close to the metal where you have the most information about the error and deal with it there, let everything else bubble up, as in most cases the only solution will be to bring your app down.

    When you do handle an exception, log as much detail about the exception as needed to figure out what happened later. Take corrective action and if necessary fire an custom exception to be handled at the next level.

    Only respond to custom exceptions outside the DAL as doing otherwise will couple the DAL to the next layer and of course you are in a worse position to deal with it outside the DAL.

    So for example in an insert method, you'd catch primary key, unique key, foreign key and not null violations. These are things you'd want to let the user know about, everything else is unexpected and there is nothing the user can do about it, so log it and exit.


  • Advertisement
  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    Are you saying my suggestion would be horrible to maintain?


  • Registered Users Posts: 2,016 ✭✭✭Colonel Panic


    Ugh, tell me you're not wrapping EF in some DAL/Repository style thing.

    Does your service layer not just have an EF context? You can catch exceptions it throws and throw user friendly errors up to your service layer caller to display to the user.

    Don't overthink it!


  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    Ugh, tell me you're not wrapping EF in some DAL/Repository style thing.

    Does your service layer not just have an EF context? You can catch exceptions it throws and throw user friendly errors up to your service layer caller to display to the user.

    Don't overthink it!

    Sorry but that's a bad recommendation for someone starting out in my opinion.

    Why would you embed a proprietary framework such as EF into your entire application? What happens if/when you want to change how you persist data?

    The repository pattern is well established and I've never heard anyone suggest it's bad. It's there to abstract how data is retrieved and persisted leaving the service layer to handle the business logic.


  • Registered Users Posts: 444 ✭✭RickBlaine


    John_Mc wrote: »
    Sorry but that's a bad recommendation for someone starting out in my opinion.

    Why would you embed a proprietary framework such as EF into your entire application? What happens if/when you want to change how you persist data?

    The repository pattern is well established and I've never heard anyone suggest it's bad. It's there to abstract how data is retrieved and persisted leaving the service layer to handle the business logic.

    I agree. I would never put the EF context in the service layer.

    All the EF stuff is in its own data layer and deals with entity objects. Then the various methods in the data layer returns application models. I use AutoMapper to map the entity to the model.


  • Registered Users Posts: 2,016 ✭✭✭Colonel Panic


    John_Mc wrote: »
    Sorry but that's a bad recommendation for someone starting out in my opinion.

    Why would you embed a proprietary framework such as EF into your entire application? What happens if/when you want to change how you persist data?

    The repository pattern is well established and I've never heard anyone suggest it's bad. It's there to abstract how data is retrieved and persisted leaving the service layer to handle the business logic.

    I didn't suggest embedding it into the entire application.

    The repository/unit of work pattern is fine, but EF already represents a repository/unit of work. It's this dogma about having layers everywhere to let you slot in different implementations of things that annoys me.

    Furthermore, change how you persist data... This happens very infrequently in reality.


  • Advertisement
  • Moderators, Business & Finance Moderators Posts: 10,001 Mod ✭✭✭✭Jim2007


    John_Mc wrote: »
    Are you saying my suggestion would be horrible to maintain?

    Most certainly. You end up with one massive global handler and every time you need to make a little tweak to handle a particular situation it becomes a saga because your trying to fix it, well away from where it occurred, it can have side effects and you've got reams of stack track to go through to find out what is happening, if you even bothered to log the stack trace....


  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    I didn't suggest embedding it into the entire application.

    The repository/unit of work pattern is fine, but EF already represents a repository/unit of work. It's this dogma about having layers everywhere to let you slot in different implementations of things that annoys me.

    Furthermore, change how you persist data... This happens very infrequently in reality.

    I wouldn't consider 3 layers to be over the top to be honest. And just because something happens infrequently doesn't mean you shouldn't allow for it to be possible. It makes sense that an important and fundamental part of your application belongs in its own layer/project/assembly in my opinion.
    Jim2007 wrote: »
    Most certainly. You end up with one massive global handler and every time you need to make a little tweak to handle a particular situation it becomes a saga because your trying to fix it, well away from where it occurred, it can have side effects and you've got reams of stack track to go through to find out what is happening, if you even bothered to log the stack trace....

    Not really though. Create some custom exceptions, like NotFoundException for example, which extends Exception and have your Repo throw that (possibly with a message). For example, the Id passed to GetById is not found.

    Your Global Error handler has a switch on exception type and returns a 404 or redirects to Not Found page if the exception is of type NotFoundException.

    Realistically you'll only have a few types of custom exception and fallback to a generic exception by default. The Global Error handler shouldn't be long at all and is responsible for logging the error and returning the appropriate response to the client.

    Being a contractor for the last 7 years, I've worked on a lot of enterprise applications and all of them have handled it like this.

    Try/Catch will pollute your code with unnecessary blocks in each and every method and is a waste of time and energy for no reason at all.


  • Moderators, Business & Finance Moderators Posts: 10,001 Mod ✭✭✭✭Jim2007


    John_Mc wrote: »
    Being a contractor for the last 7 years, I've worked on a lot of enterprise applications and all of them have handled it like this.

    And being a contractor for 30 years.... I've seen what that kind of global crap causes and we just don't do it, at least not if your the lead developer on a couple of major European banking systems in any case.


  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    Jim2007 wrote: »
    And being a contractor for 30 years.... I've seen what that kind of global crap causes and we just don't do it, at least not if your the lead developer on a couple of major European banking systems in any case.

    You're mistaken if you think I'm going to be impressed that you're in banking to be honest :D

    To the Op, have a read of this and do some more research and see what solution you prefer yourself. There are pros and cons with most solutions you go with so it's about weighing them up and seeing which suits your needs best.


  • Registered Users Posts: 444 ✭✭RickBlaine


    The sense I'm getting from this discussion is that if I want to try some action to try to recover from the exception, I should handle it close to where it is raised, e.g. in the same layer as EF.

    However, if I simply want to log the exception and return an error code and error message to the front end, I can just let the exception bubble up to a higher layer.

    Would I be correct?


  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    RickBlaine wrote: »
    The sense I'm getting from this discussion is that if I want to try some action to try to recover from the exception, I should handle it close to where it is raised, e.g. in the same layer as EF.

    However, if I simply want to log the exception and return an error code and error message to the front end, I can just let the exception bubble up to a higher layer.

    Would I be correct?

    Yes. If you think there's a good chance of an exception occurring then you should catch it locally where it happens. Consuming a third party API which is dodgy would be a good example.

    I would not recommend try/catching everywhere by default. Do it only when necessary.


  • Registered Users Posts: 772 ✭✭✭pillphil


    John_Mc wrote: »
    ...And just because something happens infrequently doesn't mean you shouldn't allow for it to be possible...

    Obviously not a consultant :P


  • Registered Users Posts: 2,790 ✭✭✭John_Mc


    pillphil wrote: »
    Obviously not a consultant :P

    I worked as one for 4 years actually. Very poor standards in general in that industry!


Advertisement