how can I do that ?
void x()
{....
if (...)
{try
{}
catch (ComException com)
{ throw com}
finally // in any case, executed fine!
{...instructions.......}
}
... instructions...// not executed in case of exception because the finally can't embrace the following code too... but this block of code needs to be executed in any case too...
{}
}
That's incorrect logic. The else block will not be executed if the code goes into the if statement.
If you really need it to be executed even in case of exception, copy the code from the else block into the finally block.
EDIT: So I think what you want is this:
try
{
if()
{
try
{
//Code
}
catch(ComException e)
{
throw e;
}
}
}
finally
{
/*....instructions.....*/
}
The reasoning behind this is that the inner try will execute the code if the IF statement is true, and will catch and then re-throw the ComException if it encounters it. The code in the finally block will execute regardless of either the IF statement or the catching of a ComException.
Does this explain the position better?
With apologies to dtb; he answered this first, I just added an explanation.
Move the code in the "else" branch to a separate method. Then call that method from both the "else" and the "finally".
Are you looking for this?
try
{
if (...)
{
try
{
...
}
catch (ComException)
{
...
}
}
}
finally
{
...
}
The finally block is executed regardless of whether the condition holds or not.
If something needs to be executed, it must go in the finally block. Finally always executes, no matter what happens in try and catch blocks. The context of the "else" is really outside your try/catch/finally segment.
Related
try
{
operation1();
operation2();
...
}
finally
{
try
{
finalizer_operation1();
finalizer_operation2();
}
finally
{
very_critical_finalizer_operation_which_should_occurs_at_the_end();
}
}
Is this ok? To have finalizer as another try/finally block (because finalizer_operationX() may throw and I must ensure that very_critical...() will happens at the end.
Quick googling for try in finally block brings nothing (will delete question if you give me a duplicate link), it should work, but I am unsure in design and possible problems with it.
I would not write the code this way. I don't like nesting try/catch/finally constructs. I prefer one per method.
My preference is to wrap each of those calls in its own method.
try
{
operation1();
operation2();
...
}
finally
{
cleanup();
}
public void cleanup() {
try
{
finalizer_operation1();
finalizer_operation2();
}
finally
{
very_critical_finalizer_operation_which_should_occurs_at_the_end();
}
}
Of course it is. A finally block will execute if control flow enters the corresponding try block.
The only exception is a call that shuts down the VM.
What happens here ?
I wonder whether SaveError() can be called after exception block ?
Does the Main.cs get noticed about caught error?
I want to see the story behind this case.
What is the value of the variable "a" ?
note: Asume there has been an error in try block.
Main.Cs
public void RunAll()
{
....
int a = doSubTask();
}
A.cs
public int doSubTask(){
try{
..
..
return 1;
}catch(Exception Ex)
{
throw new AppException("Error", ex);
}
finally
{
SaveError();
return -1;
}
return 0;
}
The return 0; after the finally is redundant since finally will be called always even if there was an exception inside the cache or not.
Anyway, leaving the finally block with return will cause you a compilation error which means in your case, since you are throwing an exception from inside the catch block, a will not be set by any value.
First of all, you can't return value within finally block, C# does not allow this.
finally always executes even if there are errors (i.e. control goes in catch block). So in your case, the return value will always be -1, it does not matter whether exception was thrown or not.
The last statement return 0; is non-reachable.
I guess you can modify your code like this. You shouldn't use more than one "return" key in a method.
public int doSubTask()
{
int retval = 0;
try
{
//to do
retval = 1;
}
catch (Exception Ex)
{
SaveError();
retval = -1;
throw new AppException("Error", ex);
}
finally
{
// do something even there is error or not
}
return retval;
}
Short answer: it depends from you machine ^^
As you can see in this MSDN article: http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx ,
if the exception is unhandled it's up to your system to decide if the Finally statement is executed or not.
Also: you can't return a value in a finally statement.
The whole method Foo seems a bit confusing to me.
If your goal is to try a "risky" operation and handle the error you shouldn't rethrow the exception without having the outer code handle that.
So, if you want the RunAll method to know if there's been an error, you should set it's code inside a try-catch statement and rethrow the exception in the Foo method, without the finally statement so the rethrown exception "bubbles up" the chain and gets handled in the calling method :)
It is not allowed to try to "leave" a finally block, so it will not be valid to say return -1; inside the finally block. So your code will never compile.
error CS0157: Control cannot leave the body of a finally clause
Hence, there exists no question "what will happen when it runs".
I read that finally key make a try-catch block final work, even function throw exception or not. But I wonder what is different if I don't put a code inside a finally block (like Function_2 below), which is the way I'm using to coding. Thank You!
void Function_1()
{
try
{
throw new Exception();
}
catch
{
}
finally //Have finally block
{
Other_Function();
}
}
void Function_2()
{
try
{
throw new Exception();
}
catch
{
}
Other_Function(); //Don't have finally block
}
if I dont put a code inside a finally block (like Function_2 below)
if you don't put code inside finally , until unless you won't get an exception that code block will be executed.
but if you get an exception before that code block (which was not kept inside finally) will not be executed as the control returns from there itself.
but if you keep your code in finally , it will be executed irrespective of the situation.
Example:1 without finally block
try
{
//throw exption
}
catch
{
//return from here
}
//below statement won't get executed
Other_Function();
Example:2 with finally block
try
{
//throw exption
}
catch
{
//return from here if finally block is not available
//if available execute finally block and return
}
finally
{
//below statement surly gets executed
Other_Function();
}
A finally block, refers to a block of statements that is always executed, regardless of unexpected events or exceptions that may occur during an application's execution. The execution of a finally block is intended to release resources, such as database connections, which are usually available in limited quantities.
From MSDN:
Usually, when an unhandled exception ends an application, whether or
not the finally block is run is not important. However, if you have
statements in a finally block that must be run even in that situation,
one solution is to add a catch block to the try-finally statement.
Alternatively, you can catch the exception that might be thrown in the
try block of a try-finally statement higher up the call stack. That
is, you can catch the exception in the method that calls the method
that contains the try-finally statement, or in the method that calls
that method, or in any method in the call stack. If the exception is
not caught, execution of the finally block depends on whether the
operating system chooses to trigger an exception unwind operation.
Code in finally blocks is always executed. Finally provides a construct for ensuring the correct execution of programs. It ensures a block of statements are always reached before the enclosing method is exited.
his program shows how the finally clause is part of the control flow in programs. In this program, a random number is generated. This value is used to determine whether to throw an exception, immediately return, or do nothing.
using System;
class Program
{
static void Main()
{
try
{
// Acquire random integer for use in control flow.
// ... If the number is 0, an error occurs.
// ... If 1, the method returns.
// ... Otherwise, fall through to end.
int random = new Random().Next(0, 3); // 0, 1, 2
if (random == 0)
{
throw new Exception("Random = 0");
}
if (random == 1)
{
Console.WriteLine("Random = 1");
return;
}
Console.WriteLine("Random = 2");
}
finally
{
// This statement is executed before the Main method is exited.
// ... It is reached when an exception is thrown.
// ... It is reached after the return.
// ... It is reached in other cases.
Console.WriteLine("Control flow reaches finally");
}
}
}
Source
The code below will complain
try
{
session.Save(obj);
return true;
}
catch (Exception e)
{
throw e;
return false; // this will be flagged as unreachable code
}
whereas this will not:
try
{
session.Save(obj);
return true;
}
catch (Exception e)
{
return false;
throw e;
}
I dont get it...I thought my csc101 told me that return statements should always be the last statement in a function and that it exits the function and return control to the calling code. Why does this defy my professor's logic, and why does only one of these generate a warning?
return will exit the method; throw will also exit the method, assuming it is not inside the try. It can only exit once!
So regardless of the order - the first of the throw / return effectively end the method.
As more general feedback, though: if the intent is to return false upon failure, all you need is:
try
{
session.Save(obj);
return true;
}
catch
{
return false;
}
Personally, I would say that this is bad code - it hides the actual problem from the caller, making it very hard to debug. It tells us nothing of why it failed. I would say that the better approach is simply to let the exception bubble. In that case, there is no point returning true, because we would never return false - and there is no point catching an exception just to re-throw it. So the entire method becomes:
session.Save(obj);
(nothing else required whatsoever)
If your question is "why does only one of these generate a warning": a fair question, but the compiler isn't required to spot either of them for you. Perhaps it should spot it. I suspect that gmcs would spot this and warn about it - the compiler in mono is far more willing to point out stupidity.
Edit: as expected, [g]mcs outputs:
Program.cs(15,13): warning CS0162: Unreachable code detected
Program.cs(28,13): warning CS0162: Unreachable code detected
for the code below - so it does indeed report both uses as warnings:
class Program
{
static void Main() { }
static void DoSomething() { }
bool ReturnFirst()
{
try
{
DoSomething();
return true;
}
catch
{
return false;
throw; // line 15
}
}
bool ThrowFirst()
{
try
{
DoSomething();
return true;
}
catch
{
throw;
return false; // line 28
}
}
}
You are wrong: both your examples raise the Dead code compiler error because both throw and return mark the exit point of a method and no further code is allowed beyond that point.
However, whether the compiler allows it or not, the code below either the throw or the return is still dead and will never get a chance to execute.
(NOTE: this question was initially tagged as Java and my first sentence pertains to Java compiler semantics)
Because any code after the return statement within a code block will be unreachable.
This answer is based on C# and may or may not be applicable to Java.
In this case, you do not actually need the return statement. throw will be the last step of the function.
In this example, both return and throw will end the current function. Regardless of which way around you put them, then first will always prevent the second from being reachable.
NOTE: The exception to when a throw statement would end the function is if it was to be wrapped in a try block. In this case, the throw function would end execution of the remaining try block code, and move to the most relevant catch block - or finally block if a catch is not applicable.
Your code should look like this:
try
{
session.Save(obj);
return true;
}
catch(Exception e)
{
throw e;
}
However, there is not much point in having the try/catch anyway if all you are doing is re-throwing the exception.
To specifically answer your only question:
Why does this defiles my professor's logic?
Well either your professor is wrong, or you have misunderstood them
The "return false;" in the catch block is unreachable because of the "throw e;" just before it. When the code executes in the catch block the first line is a throw which means you immediately throw the exception to the calling method and therefore any following code does not get executed.
try
{
session.Save(obj);
return true;
}
catch(Exception e)
{
throw e; //Throws exception to calling method
return false; //this will be flagged as unreachable code
}
I hope this helps.
I have a question that might seem fairly simple (of course if you know the answer).
A certain function I have calls another function but I want to continue execution from the caller even though the callee has thrown an exception. Let me give you an example:
something function1()
{
try
{
//some code
int idNumber = function2();
//other code that need to execute even if function2 fails
return something;
}
catch(Exception e)
{//... perhaps something here}
}
EDIT: function1 also has a return statement so nothing can in fact crash on the way
In function2 I need to do stuff but I only need to log if anything fails, example:
int function2()
{
try
{
//dostuff
}
catch(Exception e)
{
//Log stuff to db
}
}
ok, now my question is, what should I do if I wanted to continue execution in function1 even if function 2 throws an error?
Sometimes I mix up if I should do throw; or throw e; or throw nothing at all (leave catch block empty)
Leaving the catch block empty should do the trick. This is almost always a bad idea, though. On one hand, there's a performance penalty, and on the other (and this is more important), you always want to know when there's an error.
I would guess that the "callee" function failing, in your case, is actually not necessarily an "error," so to speak. That is, it is expected for it to fail sometimes. If this is the case, there is almost always a better way to handle it than using exceptions.
There are, if you'll pardon the pun, exceptions to the "rule", though. For example, if function2 were to call a web service whose results aren't really necessary for your page, this kind of pattern might be ok. Although, in almost 100% of cases, you should at least be logging it somewhere. In this scenario I'd log it in a finally block and report whether or not the service returned. Remember that data like that which may not be valuable to you now can become valuable later!
Last edit (probably):
In a comment I suggested you put the try/catch inside function2. Just thought I would elaborate. Function2 would look like this:
public Something? function2()
{
try
{
//all of your function goes here
return anActualObjectOfTypeSomething;
}
catch(Exception ex)
{
//logging goes here
return null;
}
}
That way, since you use a nullable return type, returning null doesn't hurt you.
Why cant you use the finally block?
Like
try {
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK
} finally {
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
EDIT after question amended:
You can do:
int? returnFromFunction2 = null;
try {
returnFromFunction2 = function2();
return returnFromFunction2.value;
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK
} finally {
if (returnFromFunction2.HasValue) { // do something with value }
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
Or you can encapsulate the looping logic itself in a try catch e.g.
for(int i = function2(); i < 100 /*where 100 is the end or another function call to get the end*/; i = function2()){
try{
//ToDo
}
catch { continue; }
}
Or...
try{
for(int i = function2(); ; ;) {
try { i = function2(); return; }
finally { /*decide to break or not :P*/continue; } }
} catch { /*failed on first try*/ } finally{ /*afterwardz*/ }
just do this
try
{
//some code
try
{
int idNumber = function2();
}
finally
{
do stuff here....
}
}
catch(Exception e)
{//... perhaps something here}
For all intents and purposes the finally block will always execute. Now there are a couple of exceptions where it won't actually execute: task killing the program, and there is a fast fail security exception which kills the application instantly. Other than that, an exception will be thrown in function 2, the finally block will execute the needed code and then catch the exception in the outer catch block.
Do you mean you want to execute code in function1 regardless of whether function2 threw an exception or not? Have you looked at the finally-block? http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
In your second function remove the e variable in the catch block then add throw.
This will carry over the generated exception the the final function and output it.
Its very common when you dont want your business logic code to throw exception but your UI.