Logging Exceptions Location within a DAL Class
I am not sure where the best location to handle my exceptions in my DAL class. I have some code that does a read, and populates a list of business objects like the pseudo-code below:
public List<MyObject> GetMyObjects()
{
while (dataReader.Read()
开发者_如何学编程{
try
{
//populate business object
}
catch
{
//log exception?
}
}
}
The question I have is that I'm not sure if my logging class should be in this class, but throwing an exception isn't acceptable since it will cause the code to exit this method. What have the rest of you done in this situation?
NOTE: Per our business rules, the objects that cannot be loaded properly just need to be logged (this is due to some issues we are resolving in the database at the same time this code is being refactored).
General rule of exception handling: Only catch and suppress the exception if you can do something about it, and if you can do something about it, there's no reason to log it :)
You can catch it in order to log it if that's what you want to do, but if that's the only reason, you must rethrow it afterwards.
Now ask yourself this question: Do I care about exceptions only in my DAL class, or do I care about exceptions in general?
Personally, I don't much care about where the exception was thrown when it comes to logging it. What I do care about is that it gets logged at all, so instead of baking in exception handling in particular classes, I deal with it in a general way.
Exception Handling is a Cross-Cutting Concern and should be treated as such. In other words, it's much better to have a general purpose exception handler/logger for the entire application. Here's an example of what I mean.
Typically, I would say that the DAL is the wrong place to be handling exceptions. I would expect the caller to properly handle them. With your requirements as per your note...I don't think you have much choice.
My suggestion would be that, if you have to handle Exceptions in the DAL, modify the method slightly to allow the caller to inject a Logging framework into the method so that you're DAL isn't concerned with what Logging tool is being used:
public List<MyObject> GetMyObjects(ILogger logger)
{
while(dataReader.Read())
{
try
{
// Do Stuff
}
catch(Exception ex)
{
logger.Log(ex.Message);
}
}
}
It'll make the code look a little more complicated, but this method insures that your DAL isn't tightly coupled to a single Logging Framework.
Putting logging calls in your DAL is quite normal.
As long as your logging code doesn't actually use the DAL.
I would recommend using a logging framework such as Log4Net.
One of the reasons I like to do logging in the DAL is that you have a lot of useful data present about the error and the context. For example, you have the connection string, the name of the stored procedure called or the text of the SQL that was run. You can add all of that information to the log record. If you let the exception bubble up through the code layers, some of this data will no longer be available.
I would still rethrow the exception so that the appropriate layer(s) can either handle it or degrade gracefully.
精彩评论