C# - using return in catch clause - c#

I saw a similar question here, but there are still some things I don't understand. As far as I know when you use try-catch block, if an exception is thrown the catch block will be executed right after and no code after the catch clause in the same code block will be executed. So if I get it right if we have:
try
{
// do something
// throw an exception for some reason
}
catch (Exceptiox ex)
{
// do something when there is and exception thrown
}
// some code that will never be runned if and exception was thrown above
I'm not 100% sure that the catch stops further execution outside its scope but this is one of my questions so correct me if I'm wrong.
So what's the point of using return in a catch block if you don't need to return any value at all? I see this in some methods from inherited code I'm working on. For example:
public void DeleteImage(AppConfig imageInfo, string imageName)
{
string imgPath = imageInfo.ConfigValue.ToString();
try
{
File.Delete(imgPath + "\\" + imageName);
}
catch (Exception ex)
{
logger.Error(ex.ToString());
return;
}
}
Here there is no need to do anything besides logging the error. Why then use return. Is it a mistake? Won't the method finish if you don't return explicitly? If there was more code after the catch clause would it be executed if the return wasn't there and the catch was used only for logging the error?

I'm not 100% sure that the catch stops further execution outside it's
scope but this is one of my questions so correct me if I'm wrong.
No, that's incorrect. Execution will continue normally after the catch block, unless some code inside the block changes the flow (e.g. throw or return).
Therefore return is necessary if you don't want execution to continue. Even if there is currently no code after the catch block, IMHO it's OK to make it more explicit that "handling this type of exception involves not executing any code after this point".
That said, you should be wary of catch (Exception ex) -- catching all types of exception should always be questioned and is almost always not quite the right thing to do (although in this case it's for logging, which is an "allowed exception to the rule").

I'm not 100% sure that the catch stops further execution outside it's scope but this is one of my questions so correct me if I'm wrong.
No, it doesn't. If the catch block doesn't either rethrow or return, execution will continue from the end of the try/catch statement.
In the sample you've given, the return statement is pointless. If there were code after the catch block, that would be a different matter, as the return statement would make the method return immediately.
It's not a mistake to have a return statement in a catch block like that, in that it's perfectly valid code, and will presumably still execute as intended - but it's definitely odd. It could well be that it was cut/paste from a method where the return statement was important.
(It's also almost always a bad idea to catch Exception, but that's a different matter.)

If there would be no return statement and further any code instead of that, then that code would have got executed. And you are allowed to return any thing from catch block. There is no restrictions for it.

Related

What is the finally block for compared to just writing code after the try statement?

In other words, how are these two different?
try
{
// Something that can throw an error
}
catch
{
// Handle the error
}
finally
{
// Something that runs after the try statement
}
vs.
try
{
// Something that can throw an error
}
catch
{
// Handle the error
}
// Something that runs after the try statement
finally block always executes.
You can be sure, that this block will be executed no matter what.
Literally it is something like:
Try something, catch some exceptions(if told to and if they are there) and execute the
finally block finally.
If there is a break in the try block or an exception, it may cause the program to halt. In cases like these code that is mandarory to be executed, like closing open connections and returning items to the connection pools are writen in the finally block. The finally block ensures that the code written inside it will be executed.
If you only ever use general catches (i.e. catch without args or catch(Exception ex)), whether to put code in finally or after try/catch is basically a stylistic choice, as both a finally block and code after a try/catch will execute in any situation (barring deliberate escape mechanisms such as return).
However, if you use a narrow catch, and the exception isn't caught, what will happen is the finally block will still execute, however the code after the try/catch won't.

Is finally block in C# a must?

What is the difference between 2 conditions? Every time when method1 or method2 runs, there should be a code block that is required to run. It seems to me that 2 method are the same.
// example method1
void Method1(void)
{
try
{
// do something
}
catch (Exception ex)
{
// do something
}
finally
{
// do something whenever method1 runs
}
}
// example method2
void Method2(void)
{
try
{
// do something
}
catch (Exception ex)
{
// do something
}
// do something whenever method2 runs
}
Finally block seems to be unnecessary for me.
In your first example, you could re-throw the exception and the code inside the finally would still run. This would not be possible in the second example.
If you choose not to re-throw the exception, then yes there is little difference. However, this is considered bad form - very rarely should you need to consume an exception that you cannot explicitly handle.
It is a keyword to help you with code execution flow. When you throw an exception the execution flow of the code is affected (like using return), the finally keyword allows you to express that when an exception occurs (or you return from a try) you still want execution to do something as it's leaving.
To answer the question facetiously, it is a must when you need it and not when you don't.
Further Reading
To be on the safe side, before you attempt to start making use of this keyword, please read the documentation for it:
http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
And the exception handling keywords in general:
http://msdn.microsoft.com/en-us/library/s7fekhdy.aspx
Examples
Catch an exception to do something with it, then re-throw it. Use finally to call any tidy-up code:
try
{
OpenConnectionToDatabase();
// something likely to fail
}
catch (Exception ex)
{
Log(ex);
throw;
// throw ex; // also works but behaves differently
}
// Not specifying an exception parameter also works, but you don't get exception details.
//catch (Exception)
//{
// Log("Something went wrong);
// throw;
//}
finally
{
CloseConnectionToDatabase();
}
Don't register any interest in catching exceptions, but use finally to tidy-up code:
try
{
OpenConnectionToDatabase();
// something likely to fail
}
finally
{
CloseConnectionToDatabase();
}
Return from your try because it looks nicely formatted, but still use finally to tidy-up code:
try
{
OpenConnectionToDatabase();
return 42;
}
finally
{
CloseConnectionToDatabase();
}
As you know the code written inside the finally block always runs.
Please have a look onto the following point written below, it will clear your all confusion.
Finally is used for Resource management. Mainly for releasing an resources. It always runs independent upon the Exception.
As we know catch is used for handle an exception, but sometimes it fails to handle to an External exception. Then the finally block is used to handle that exception to perform the operation.
The code in the finally block will run anyway after the try-catch, it is very usefull for clean up.
try
{
// open resources
}
catch (Exception ex)
{
// something bad happened
}
finally
{
// close resources that are still opened
}
This will behave very differently depending on whether you return from the try, for example. Also - the finally will run even if the catch throws an exception (or re-throws the original exception), which will not happen without the finally.
So: it isn't required, but it will behave differently. So if you want the code to happen, put it in the finally.
In many ways, try/finally is much more common than try/catch or try/catch/finally.
You do not absolutely have to have the finally block, however, having it guarantees that the code within it will always run (unless there is an exception in the finally!).
Consider the following:
void Method2(void)
{
try
{
// do something
}
catch (Exception ex)
{
// do something
throw;
}
// do something whenever method2 runs
}
the code after the try/catch will not execute if an exception is thrown. Additionally, if the code within the catch block has an error that causes an exception (such as your logging throwing an unexpected exception) the code that should have been in the finally will not run, leaving and cleanup undone.
Also a return statement will cause that code to not be run, while the finally will still be executed (also, here you can see that the catch can be skipped too, allowing any exceptions to propogate upwards - AFTER executing the finally):
void Method2(void)
{
try
{
// do something
return
}
finally
{
// do something whenever method2 runs
}
}
Whenever you have cleanup code that must be run at the end of a method, use finally (or if your objects implement IDisposable use the using statement).
The finally block ensures that any code within it ALWAYS gets executed so if you have a return statement inside your try block or rethrow an exception within your catch block, the code inside the finally block will always execute.
It is a must if you need to ensure that something happens regardless (e.g. disposing of a resource etc)
The big difference is that try...catch will swallow the exception, hiding the fact that an error occurred. try..finally will run your cleanup code and then the exception will keep going, to be handled by something that knows what to do with it.

throw exception in the try block rather than catch block?

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!

Can't declare unused exception variable when using catch-all pattern

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.

Thoughts on try-catch blocks

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

Categories

Resources