I've inherited code in our project which looks like this. It's a method in a class.
protected override bool Load()
{
DataAccess.SomeEntity record;
try
{
record = _repository.Get(t => t.ID.Equals(ID));
if (record == null)
{
throw new InvalidOperationException("failed to initialize the object.");
}
else
{
this.ID = record.ID;
// this.OtherProperty = record.SomeProperty;
// etc
}
}
catch (Exception)
{
throw;
}
return true;
}
If I then call this Load method from my UI layer, I'd probably want to have a try catch block to catch any exception caused by the failure to Load the instance, e.g. InvalidOperationException, but the above code feels wrong to me.
Won't the InvalidOperationException be swallowed by the catch statement? that catch statement will also catch potential problems with _repository.Get, as well as potential problems with the setting of properties if the record is valid.
I thought I should perhaps restructure it by adding more try catch statements to handle the Get operation and property setting operations separately, or add more catch blocks handling different exceptions, but I asked a colleague, and he suggested that the try catch is irrelevant in this case, and should be removed completely, leaving it like:
protected override bool Load()
{
DataAccess.SomeEntity record;
record = _repository.Get(t => t.ID.Equals(ID));
if (record == null)
{
throw new InvalidOperationException("failed to initialize the object.");
}
else
{
this.ID = record.ID;
// this.OtherProperty = record.SomeProperty;
// etc
}
return true;
}
I'd like some second opinions, I've only just started taking an interest in exception handling, so I'd like to make sure I am doing it the right way according to best practices.
When you do this:
catch (Exception)
{
throw;
}
You are essentially not handling the exception. That does not however mean you are ignoring it. The throw statement will propagate the exception up the stack. For the sake of clean readable code your final example is much better.
If you're catching exceptions in the calling method ( Ithink) you should only catch exceptions which you expect. If the exception is a problem for Load(), then throw a new exception to the calling method, with better information about the exception.
Excellent! You are definitely on the right track. The previous implementation doing nothing other than re-throwing exceptions which is unnecessary. You should only handle specific exceptions that you are anticipating in the business layer, otherwise let them naturally go up the call stack up to the UI layer.
As best practice, only re-throw exceptions when you want to add some additional debug information, in which case you will need to define a custom exception
The exception will be caught by the catch statement but since it has a throw statement, it'll throw the exception back out. This has the same effect as if you didn't have a try/catch at all, so your colleague is right in suggesting leaving it out.
There isn't much of a point to adding exception-handling code if you don't actually handle the exception in any way.
I agree with your colleague, you should only catch exceptions that you know need to be caught. I typically leave out any try catch blocks unless I know exactly why I need it in a particular situation. This is because you tend to hide the real bugs in your code if you just put try catch block around everything. Leave the error handling off until you absolutely need it - start off with a single global error handler at the highest point in the application - if this is asp.net you can hook the application error event and log errors there, but my point is don't add try catch blocks unless you know why your adding them and write code that handles error cases not traps them.
Enjoy!
Related
assume we have following peace of code in C#:
try{
....
try{
throw new Exception1("exception1");
}catch(Exception exception){
...
throw new Exception2("exception2");
}
}catch(Exception exception){
...
log(exception.message);
}
is it possible in log point(outer catch) to access exception1 object and log that one as well?
Here are two reasonable examples of what I think you are talking about. They illustrate what I was trying to describe in the comments as well as what #Jonesopolis describes.
First, my case. Say you are writing a utility that calls some lower-level service that may throw. You may want to describe the behavior of the utility in a way that the exceptions that may bubble up have more meaning to the caller. In this case, I've documented that my utility will throw an ApplicationException if there is a problem.
I do this from two places, the first one when I check some pre-conditions (that the path name is neither null or empty and that it is a valid file name (I'm assuming that there is an IsValidFileName function I can call)).
But the other place is that if I try to do the operation and it throws (I haven't checked that File.ReadAllLines actually ever throws an IOException, but I'm guessing it can). In this case, I don't want to burden my users with catching a possible IOException, instead, I translated it into an ApplicationException that I document. I wrap the IOException with a catch and throw of my ApplicationException, but I include the IOException as the inner exception so that debugging and tracking down other issues works. The code looks like:
public IEnumerable<string> AccessFile(string pathName)
{
if (string.IsNullOrEmpty(pathName) || !IsValidFileName(pathName))
{
throw new ApplicationException("Invalid Path Name");
}
try
{
var result = File.ReadAllLines(pathName);
return result;
}
catch (IOException ex)
{
throw new ApplicationException("Error Accessing File", ex);
}
}
It's that second parameter to the ApplicationException that sets up the inner exception. This pattern is very common.
The other example is what #Jonesopolis describes.
Here I have a work function doing something. My application architecture demands that I do logging at the level of whatever the DoSomethingImportant function is at. So, it catches any exceptions that get thrown at a lower level. However, that code wants to bubble up any exceptions to the DoSomethingImportant function's caller. Here, it just uses the throw keyword with no argument. That rethrows the current exception and lets it bubble through.
It's important to use throw; with no arguments, and not throw ex;. The former allows the existing exception to bubble up. The latter unwinds the stack at the catch site, and then throws a new exception, losing all the stack information that might point to the faulting location.
This is the typical code that I'm talking about. It's also a very common pattern:
public void DoSomethingImportant()
{
try
{
DoSomethingLowLevel();
}
catch (Exception ex)
{
GetLogger().Log(ex);
throw;
}
}
I have a couple of questions around exception management for a website:
in the catch block can I have a static class with a handle exception method that handles the exception like so:
catch (Exception ex)
{
throw ExceptionHandler.HandleException(...);
}
where ExceptionHandler.HandleException is a static method that returns a variable of type System.Exception. Is this a good practice? Any possible problems with this approach? Will it be thread safe?
In my application I have a DAL layer that is called by the Business layer and the Business layer is called by the UI. So, is it a good practice to just re-throw all Custom exceptions so they bubble up right up to the UI where they get displayed whereas System.Exception types get logged and I throw a custom exception in the catch block?
for eg in DAL and Business Layer like so:
catch (CustomExceptionBase ex)
{
throw;
}
catch (Exception sysEx)
{
ICustomExceptionBase ex = new SysException(sysEx);
ex.Handle();
throw BusinessException("Some problem while serving your request");
}
In the UI layer like so
catch (CustomExceptionBase ex)
{
//when custom exception bubbles up; code to display text to user on screen
}
catch (Exception sysEx)
{
ICustomExceptionBase ex = new SysException(sysEx);
ex.Handle();
//display error on screen;
}
Here CustomExceptionBase implements ICustomExceptionBase and inherits Exception. SysException & BusinessException both inherit from CustomExceptionBase.
Thanks for your time...
EDIT
The intent of rethrowing in the system.Exceptions block is so that if there is a fatal error like database connection lost or something similar then I log it for the technical helpdesk and return a ticket number and rethrow the same so the user knows that something went wrong and this is your reference number to follow up. For all custom exceptions in the DAL layer or Business layer, I just bubble it up all the way to the UI where the text gets displayed.
I suspect some of the answers at least are entirely down to your architecture. In the first case it all depends on what ExceptionHandler.HandleException does exactly. Does it generate a new exception based on some criteria or is it just going to return the original exception?
Whether its thread-safe or not entirely depends on its implementation. For example in the following trivial case I'd say it was thread safe:
public static Exception ExceptionHandler.HandleException(Exception ex)
{
return ex;
}
In other cases it could easily be not thread safe. eg:
public static string message;
public static Exception ExceptionHandler.HandleException(Exception ex)
{
message = ex.ToString;
sleep(2000);
return new Exception(message);
}
The latter example clearly has scope for the message variable to be changed by another thread while this one is asleep.
As for the second... Exceptions should be handled where it makes sense to handle them. There is no hard and fast rule. If some part of the code can effect a recovery from an exception (or is willing to skip over it) then catch it at that point and not earlier. If an exception is truly fatal then nothing should be trying to catch it and pretend otherwise so you should just let it bubble right up to the top and do something like alert your user that things have crashed and that you need to restart or whatever.
So really it depends on what your custom exceptions mean. If they just mean "You want to retry this" then that is different from an exception saying "Data integrity has been compromised: 0==1". both of these may be custom so really its for you to decide where to handle things.
Yes, you can call a static exception handler inside a catch block and it will likely be threadsafe as long as you don't reference any static variables.
You should look at Microsoft's Enterprise Library. It has nearly this same design but uses exception policies defined in the web.config to control how the exception is bubbled, wrapped or discarded. Couple that with the Application Logging block and you have a complete solution.
In itself there aren't any technical problems having a static method to handle exceptions / rethrow exceptions, however from a best practices point of view having a single method that magically "handles" exceptions strikes me as a potential code smell. Exceptions are by their very name exceptional, each individual case requires thought to go into it to make sure that you are doing the correct thing and so I find it unlikely that your HandleException method will always be doing something sensible.
As an extreme example I know of one such application where pretty much every single method was wrapped in a try-catch block with a call to an static exception handler method which threw a generic MyApplicationException type. This is an extremely bad idea:
It clutters the code
It makes it harder to make sense of stack traces
It makes it very difficult for callers to catch and handle specific exceptions types
It makes throwing an exception an even bigger performance penalty than before
My favourite was a method which wasn't implemented which looked a bit like this:
void SomeException()
{
try
{
throw new NotImplementedException();
}
catch(Exception ex)
{
throw ExceptionHandler.HandleException(...);
}
}
The worst bit of this of course that it is completely mindless. As I said before exceptions are exceptional - each try ... catch block requires careful thought and consideration to be put into how it should behave, the use of a generic HandleException method is an immediate warning flag that this probably isn't the case.
Rethrowing exceptions
Generally speaking you should only rethrow an exception in two cases:
When you want to add contextual information to an exception (such as the name of the current file being processed)
When you had to catch an exception in order to handle some specific case, e.g. handling an "out of disk space" error
catch (IOException ex)
{
long win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF;
if (win32ErrorCode == ERROR_HANDLE_DISK_FULL || win32ErrorCode == ERROR_DISK_FULL)
{
// Specific "out of disk space" error handling code
}
else
{
throw;
}
}
"Bubbling" (i.e. catching and rethrowing an exception without doing anything with it) is completely unneccessary - this is what exceptions are already designed to do all by themselves!
Handling exceptions
Other people have said "exceptions should be handled where it makes sense" and I have even given this advice myself, but in hindsight I don't think thats particularly useful advice! :)
What people generally mean by that is that you should handle exceptions for specific reasons, and that you should choose where in your application to handle that exception depending on that reason.
For example if you want to display an error message to inform the user that they don't have permission to modify a file if you get an access denied error then you may have a specific try-catch block in your UI code that does this:
catch (IOException ex)
{
long win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF;
if (win32ErrorCode == ERROR_ACCESS_DENIED)
{
// Display "access denied error"
}
else
{
throw;
}
}
Note that this is very specific to this one case that we wish to handle - it catches only the specific exception type were are interested in and performs additional checks to filter down to the specific case we are interested in.
Alternatively if you want to log unhandled errors or gracefully display error messages to the user instead of an IIS 505 error screen then the place to do this is either in Global.asax or through a custom error page - ASP.Net Custom Error Pages
My point is that when handling exceptions we are are thinking carefully about what it is we want to achieve in terms of application functionality (e.g. retry logic, error messages, logging etc...) and implementing our exception handling logic to specifically address those requirements in the most targeted way possible - there is no magic exception handing framework and there is no boilerplate code.
Avoid exceptions entirely whenever possible!
I usually find that the best strategy is simply to avoid exceptions entirely whever possible! For example if your page parses user enter numbers and you want to display validation messages when they enter stupid values then validate your input up-front instead of catching exceptions:
Bad:
void DoSomething()
{
int age = int.Parse(ageTextBox.Text);
if (age < 0)
{
throw new ArgumentOutOfRangeException("age must be positive");
}
if (age >= 1000)
{
throw new ArgumentOutOfRangeException("age must be less than 1000");
}
}
void Button_Click(object sender, EventArgs e)
{
try
{
DoSomething();
}
catch (Exception ex)
{
DisplayError(ex.Message);
}
}
Good:
void Button_Click(object sender, EventArgs e)
{
int age;
if (!int.TryParse(ageTextBox.Text, out age))
{
DisplayError("Invalid age entered");
}
if (age < 0)
{
DisplayError("age must be positive");
}
if (age >= 1000)
{
DisplayError("age must be less than 1000");
}
DoSomething();
}
Users enter invalid data all of the time - handling this is really application logic and shouldn't fall into the real of exception handling - its certainly not an event that I would call "exceptional".
Of course this isn't always possible, however I find that using this strategy simplifies the code and makes it easier to follow application logic.
First of all we need to consider Exception types, In any business exception can be either BusinessException or Technical/SystemException.
In BusinessException we can send custom exceptions with error
details.
In Technical/System Exception we should not handle it, but let it
popup to UI layer.UI Can decide what error should be displayed in
case of exceptions.
In your approaches, if you handle exception or throw the custom
exception the call trace is lost.
Is it recommended to put a try-catch block in every function that opens a DB connection and log the error there, or should I rather catch errors in a higher layer of the application?
public static Category GetCategoryByName(string name)
{
Category result;
try
{
using (IDbConnection conn = ConnectionHelper.CreateDbConnectionByName(_connectionStringName))
{
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
//do stuff
}
}
}
catch(Exception e)
{
// log error here?
}
return result;
}
or rather
try
{
Category myCat = DataTools.GetCategoryByName("myCat");
// other stuff
}
catch(Exception e)
{
// log error here?
}
To sum it up: Should errors be caught as early as possible in the code? Or should I rather catch them where I have more information about the context?
As always, it depends, but in general, only catch an exception if you can do something about it, or you have specific code (e.g. a retry) to happen, or if you wish to take a very general exception and wrap it into an exception that is more specific for your business logic, otherwise, let the exception bubble up and the top most layer can log it/deal with it in a centralised fashion.
Any other way results in a lot of logging code interspersed with all the business logic.
When catching exceptions, always try to use the most accurate exception you can. For example, when using SQL Server, catch the SqlException as it will contain far more information about the exceptin than a generic Exception. You can get actual line numbers and other useful pieces of diagnostic information.
After you have extracted and logged all that is relevent, rethrow the exception or wrap it in less specific exception such as an InvalidDataException or Exception and throw that. You can then catch these more generic exceptions at higher levels.
try
{
// Execute DB call here
}
catch(SqlException exp)
{
// Log what you need from here.
throw new InvalidOperationException("Data could not be read", exp);
}
When you call this method from a higher level, you can just catch the InvalidOperationException. If the higher levels do need more detail, the InnerException will provide the SqlException which can be accessed.
The general approach to exception handling that I follow is to only catch what I can usefully act upon. There no point in catching really general Exception at lower levels of the code since you can really expect everything to go wrong or to be able to recover from every exception e.g. OutOfMemoryException or StackOverflowException.
I Usually only handle exceptions in the UI, everything below that I always throw it back to the top level. This way the stack trace has been maintained all the way though. You could always log and throw it.
I have used this before also:
try
{
DB Command
}
catch (Exception ex)
{
Log(ex)
throw; //preserve stacktrace
}
I like the first approach better, but you still have to work out what else to do i the catch block...
rethrow the exception?
throw another (more general) exception?
return null to the caller?
what is a best practice in cases such as this one:
try
{
// do something
}
catch (SpecificException ex)
{
Response.Redirect("~/InformUserAboutAn/InternalException/");
}
the warning i get is that ex is never used.
however all i need here is to inform the user, so i don't have a need for it.
do i just do:
try
{
// do something
}
catch
{
Response.Redirect("~/InformUserAboutAn/InternalException/");
}
somehow i don't like that, seems strange!!? any tips? best practices?
what would be the way to handle this.
thnx
You just don't declare the variable:
try
{
// do something
}
catch (SpecificException)
{
Response.Redirect("~/InformUserAboutAn/InternalException/");
}
This is a moot point when catching System.Exception (in your original example, which is not exactly the same as an empty catch -- an empty catch will also catch COM exceptions, for instance), but this is the correct construct to use.
If you run your code through other analysis engines (Gendarme, for instance), you will also be warned that catching a plain Exception is poor practice because it can mask other exceptions besides what you really wanted to catch. That's bitten me a few times while maintaining legacy code -- we were catching and ignoring an Exception on a file delete (or something like that), but the main logic wasn't working correctly. We should have been only catching an IOException, but we were catching and discarding the NullReferenceException that was causing the failure.
That's not to say you never should catch Exception; just rarely.
If you don't need Exception's variable to get some information from it, don't declare it
try { }
catch ( )
is equal to
try { }
catch (Exception) { }
Use this
try { }
catch (Exception ex) { var m = ex.Message; }
if you need some information to gather.
Use this
try { }
catch (FooException) { }
catch (BarException) { }
if you need to catch only specific types of exceptions, i.e. SomeAnotherException will not be caught.
It would be better if you just let the exception bubble all the way up and use an application wide exception handler or something like ELMAH. Usually you'll want to log the exception or something so there's a record of stuff failing.
Any reason why you wouldn't let unhandled exceptions simply throw and use the Application Level error handling built into ASP.NET? See How to: Handle Application-Level Errors for more details.
I usually declare it and suffer with the warning since it can be very useful to be able to look at the exception details while debugging.
There are two reasons to declare an exception variable in a catch block. To catch only specific exception types or to do something with the exception info. In your case you are doing neither so t serves no purpose.
What are your thoughts on code that looks like this:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
throw;
}
}
The problem I see is the actual error is not handled, just throwing the exception in a different place. I find it more difficult to debug because i don't get a line number where the actual problem is.
So my question is why would this be good?
---- EDIT ----
From the answers it looks like most people are saying it's pointless to do this with no custom or specific exceptions being caught. That's what i wanted comments on, when no specific exception is being caught. I can see the point of actually doing something with a caught exception, just not the way this code is.
Depending on what quality you are looking at it is not throwing the exception in a different place. "throw" without a target rethrows the exception which is very different from throwing an exception. Primarily a rethrow does not reset the stack trace.
In this particular sample, the catch is pointless because it doesn't do anything. The exception is happily rethrown and it's almost as if the try/catch didn't exist.
I think the construction should be used for handling the exceptions you know you will be throwing inside your code; if other exception is raised, then just rethrow.
Take into account that
throw;
is different than
throw ex;
throw ex will truncate the stack to the new point of throwing, losing valuable info about the exception.
public void doSomething()
{
try
{
// actual code goes here
}
catch (EspecificException ex)
{
HandleException(ex);
}
catch (Exception ex)
{
throw;
}
}
It wouldn't be, ideally the catch block would do some handling, and then rethrow, e.g.,
try
{
//do something
}
catch (Exception ex)
{
DoSomething(ex); //handle the exception
throw;
}
Of course the re-throw will be useful if you want to do some further handling in the upper tiers of the code.
Doing something like that is fairly meaningless, and in general I try not to go down the road of doing meaningless things ;)
For the most part, I believe in catching specific types of exceptions that you know how to handle, even if that only means creating your own exception with more information and using the caught exception as the InnerException.
Sometimes this is appropriate - when you're going to handle the exception higher up in the call stack. However, you'd need to do something in that catch block other than just re-throw for it to make sense, e.g. log the error:
public void doSomething()
{
try
{
// actual code goes here
}
catch (Exception ex)
{
LogException (ex); // Log error...
throw;
}
}
I don't think just rethrowing the error would be useful. Unless you don't really care about the error in the first place.
I think it would be better to actually do something in the catch.
You can check the MSDN Exception Handling Guide.
I've seen instances where generic exceptions are caught like this and then re-packed in a custom Exception Object.
The difference between that and what you're saying is that those custom Exception objects hold MORE information about the actual exception that happened, not less.
Well for starters I'd simply do
catch
{
throw;
}
but basically if you were trapping multiple types of exceptions you may want to handle some locally and others back up the stack.
e.g.
catch(SQLException sex) //haha
{
DoStuff(sex);
}
catch
{
throw;
}
Depends on what you mean by "looks like this", and if there is nothing else in the catch block but a rethrow... if that's the case the try catch is pointless, except, as you say, to obfuscate where the exception occurred. But if you need to do something right there, where the error occurred, but wish to handle the exception furthur up the stack, this might be appropriate. But then, the catch would be for the specific exception you are handl;ing, not for any Exception
Generally having exception handling blocks that don't do anything isn't good at all, for the simple reason that it prevents the .Net Virtual Machine from inlining your methods when performance optimising your code.
For a full article on why see "Release IS NOT Debug: 64bit Optimizations and C# Method Inlining in Release Build Call Stacks" by Scott Hanselman