is this exception handling code valid - c#

Will both catch blocks be hit?
try
{
DoSomething();
}
catch (AuthenticationException e)
{
throw;
}
catch (Exception e)
{
throw new AuthenticationException("Hello ");
}

It's valid (in that it will compile, build and run), but it's not good practice.
Catching the general exception only to rethrow a specific exception will cause problems. If nothing else you are destroying the original exception call stack.
In response to your edit, both catch blocks won't be hit.
If AuthenticationException is raised the first block will be executed, for any other exception the second block will be executed.

Only one exception block will be hit. And they go in order, so if DoSomething() throws an AuthenticationException, the first catch block will run.
That said, I'd probably not use try/catches here at all if all you're doing is rethrowing the exceptions. This is not a good practice. At the very least, make sure you add the original exception in your second catch as the InnerException of the AuthenticationException you're creating:
catch(Exception e)
{
throw new AuthenticationException(e.Message, e);
}

This code will throw an AutheniticationException if DoSomething throws anything. It will be the same exception if DoSomething throws AuthenticationException, or a new exception in any other case.
A side note - its not really good practise:
You loose all details of an exception which is not AuthenticationException
Why would you throw an AuthenticationException here, if the underlying code thinks there is something else wrong? A code smell for me.

Yes if you have different kinds of exceptions. (2 exceptions)
No if you wish that the first block will arrive in the second. (1 exception)

No. Both catch blocks will not be hit.
If DoSomething throws an AuthenticationException, then it will be caught and rethrown.
If DoSomething throws any other exception, a new AuthenticationException will be thrown with the message "Hello".

If DoSomething() throws an AuthenticationException then
catch (AuthenticationException e)
will be used. For all other types of exceptions,
catch (Exception e)
But you shouldn't throw a new AuthenticationException inside the second catch.

The second block will not catch the rethrown exception from the first block.

One benefit I can see for catching and rethrowing an exception would be to convey the message, "The requested operation did not succeed, but the system state is essentially as it was before the operation was attempted." While catching all exceptions in an inner routine and hoping that none of them represent a problem which should cause the main program to terminate is somewhat icky, I'm not sure what alternative design is better. One could litter the code with:
If Not Integer.TryParse(inputString, inputVar) Then
Throw New MyApp.FileLoadException("Whatever")
EndIf
but it really seems more natural to just use Integer.Parse and catch any exception that occurs. Catching and recasting general exceptions within a small domain where their expected causes are known is far less evil than swallowing general exceptions at a higher level.

Related

Are these try/catch'es equivalent?

Scenario
I have a method that does database operation (let's say). If during that operation any exception is raised, I just want to throw that exception to the caller. I don't want to do any specific task in the catch block, assuming caller will do whatever it wants to do with that exception. In this scenario, which one is appropriate exception handling technique?
try
{
// Some work that may generate exception
}
catch(Exception)
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/catch/finally?
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
Is the above equivalent to the following try/finally?
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
Which one is better than the other? Which one should be used?
No, they are not equivalent. They may be equivalent in some cases, but the general answer is no.
Different kinds of catch blocks
catch block with a specified exception type
The following will only catch managed exceptions that inherit from System.Exception and then executes the finally block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch (Exception)
{
throw;
}
finally
{
// Some final work
}
catch block without a specified exception type
The following catch block without a type specifier will also catch non-managed exceptions that are not necessarily represented by a managed System.Exception object, and then executes the finally block, which will happen regardless of whether an exception was thrown or not.
try
{
// Some work that may generate exception
}
catch
{
throw;
}
finally
{
// Some final work
}
finally block without a catch block
If you do not have a catch block at all, your finally will still be executed regardless of whether or not an exception occoured.
try
{
// Some work that may generate exception
}
finally
{
// Some final work
}
When are they equivalent?
In case your catch block doesn't specify an exception and only contains the throw; statement, the last two are indeed equivalent. In case you don't care about non-managed exceptions and your catch block only contains the throw; statement, all three can be considered equivalent.
Notes
A note about throw
The following two pieces of code contain a subtle difference. The latter will re-throw the exception, meaning that it will rewrite the exception's stack trace, so these are definitely not equivalent:
catch (Exception e)
{
throw;
}
And
catch (Exception e)
{
throw e;
}
In case you use finally with an IDisposable, the following two pieces of code are almost equivalent, but with some subtle differences:
When the object is null, the using statement won't give you a NullReferenceException
When using the try-finally technique, the variable remains in scope, although it is very discouraged to use any object after it has been disposed. However you can still reassign the variable to something else.
Something obj = null;
try
{
obj = new Something()
// Do something
}
finally
{
obj.Dispose();
}
And
using (var obj = new Something())
{
// Do something
}
You have some good answers so far, but there is an interesting difference that they did not mention so far. Consider:
try { ImpersonateAdmin(); DoWork(); }
finally { RevertImpersonation(); }
vs
try { ImpersonateAdmin(); DoWork(); }
catch { RevertImpersonation(); throw; }
finally { RevertImpersonation(); }
Suppose DoWork throws.
Now the first question at hand is "is there a catch block that can handle this exception", because if the answer is "no" then the behaviour of the program is implementation-defined. The runtime might choose to terminate the process immediately, it might choose to run the finally blocks before it terminates the process, it might choose to start a debugger broken at the point of the unhandled exception, it might choose to do anything it likes. Programs with unhandled exceptions are permitted to do anything.
So the runtime starts looking for a catch block. There's none in this try statement, so it looks up the call stack. Suppose it finds one with an exception filter. It needs to know if the filter will permit the exception to be handled, so the filter runs before impersonation is reverted. If the filter accidentally or deliberately does something that only an admin can do, it will succeed! This might not be what you want.
In the second example, the catch catches the exception immediately, reverts the impersonation, throws, and now the runtime starts looking for a catch block to handle the re-throw. Now if there is a filter it runs after the impersonation is reverted. (And of course the finally then reverts again; I assume that reverting impersonation is idempotent here.)
This is an important difference between these two code snippets. If it is absolutely positively forbidden for any code to see the global state that was messed up by the try and cleaned up by the finally, then you have to catch before finally. "Finally" does not mean "immediately", it means "eventually".
Both of the try / catch statements are equivalent in that they are re-throwing the original exception that was caught. However the empty catch is more broad (as Venemo has already stated, catching unmanaged exceptions). If you are to catch an exception and capture it in a variable you can use it for logging or you can throw a new exception while passing the original exception as an argument - making it the "inner exception".
The finally is going to function the same regardless.
Which one should be used, in a scenario where we don't need logging exception and we explicitly assume caller will handle exception being raised like writing in file stream or sending email.
If the caller will handle the exception and you do not need to log the occurrence of the exception at this level, then you should not be catching at all. If the caller will handle an exception being thrown, there is no need to catch an exception just to re-throw it.
Valid reasons to catch an exception that will be re-thrown:
throw new Exception("WTF Happened", ex); // Use as inner exception
Log exception
Use a finally block to execute some cleanup code

Try catch and re-throw exception

I saw some code the other day in one of our projects that uses a try catch and re-throws the caught exception like this:
try
{
exceptionProneCode();
}
catch(Exception ex)
{
throw ex;
}
Nothing else was done with the exception in the catch block so I'm not even sure why it's re-thrown. I can't see any benefit to actually throwing the same exception again and doing nothing with the exception.
If you re-throw an exception that's caught in the catch block, how does C# handle this? Does it get stuck in an infinite throw/catch loop? Or does it eventually leave the try catch?
Consider these two models:
1- By re-throwing ex:
catch(Exception ex)
{
throw ex;
}
you loose StackTrace. If the exception is logged somewhere the StackTrace containing immediate frames of the call stack (history of method calls) is lost.
2- In contrast by throw:
catch(Exception ex)
{
// do something here
throw;
}
you maintain StackTrace. You can do additional processing and then re-throw the exception without loosing the trace string.
It continues to throw the exception up the calls stack. One thing that this piece of code does that is different from if you didn't catch the exception, it will reset the exception location (call stacks, line #, etc) to where you re-threw the exception, so you won't have the location where the original exception was thrown.
If you're not going to actually do something in the catch block I would recommend not catching, or at the very least rethrowing with just a throw instead of throw ex.
It throws the exception to the caller. But it handles it here so it doesn't throw an unhandled exception. However, honestly, I don't see the benefit of this. Just let it throw the exception. Why? Because an exception is only unhandled if the entire call stack above it doesn't have a try ... catch. This isn't doing anything useful.
Does it get stuck in an infinite throw/catch
loop? Or does it eventually leave the try catch?
No. Yes.
The code provides no benefit and does harm to debugging as noted by everyone else.
A good catch block will catch a specific expected issue and log & continue (the problem doesn't indicate the applications state is corrupt), log and halt (because the application is now in an unknown state and continuing could wreck more harm), do something else (e.g. fall back to an equivalent technology/algorithm), wait and try again.
The default is that something is unexpected, should be logged and the application should be stopped-- either abandoning the page or if a winforms app, revert back to a known state if possible.

Throw statement with no arguments, outside catch block in a common exception handler

I have a common exception handler function:
public static void ManageException(Exception ex,
string customErrorMsg,
bool displayMessage)
which I want to call from some of the catch blocks.
After processing the exception, I want to rethrow the exception, while preserving the stack trace.
I read somewhere that I should throw statement without any parameters. The throw statement (without any params) works fine in a catch block, but in my ManageException function, it gives me a compile error:
A throw statement with no arguments is not allowed outside of a catch clause
Is there any solution to re-throw the exception with the whole stack trace and without any performance impact, from the ManageException function?
I am using C# 2.0.
You have to specify the exception to throw, as in:
throw ex;
As stated in your error, you can only re-throw exceptions (with throw;) from inside a catch block. IMHO this is really the only place it makes sense to do so as well; you are either catching the exception, or throwing it, and probably should not do both. From a method called ManageException, I wonder why you would be managing said exception, but throwing it anyway.
Perhaps you instead want to wrap the original exception in one of your own, providing additional details? In this case I would throw a new exception with ex as the InnerException, if you want to preserve that data.
From your comment, if what you are trying to do is determine whether you should re-throw an exception or not, I would suggest:
Rename your method to TryManageException and change the signature to return a bool - return a false if the exception was not managed properly and needs to be re-thrown; return a true if it was handled.
If the method returns a false (= not managed), re-throw from the catch block or do whatever else you need:
try
{
decimal oops = 5 / 0;
}
catch (Exception e)
{
if (!CommonExceptionHandler.TryManageException(e, "oops", "oops"))
throw;
}
If you really need to re-throw an exception outside the catch block, you can use the following method:
ExceptionDispatchInfo.Capture(exception).Throw();
The ExceptionDispatchInfo class is available since .NET Framework 4.5.
Usually, you shouldn't need to use this method; instead, you can a) re-throw the exception using the throw; command inside the catch block, or b) wrap the exception in another exception.
Your options are:
A. Throw in catch block:
try
{
//do stuff
}
catch (Exception ex)
{
ManageException(ex);
throw;
}
B. Rethrow in handler method:
private void ManageException(Exception ex)
{
//log or whatever
throw new Exception("See inner exception", ex);
}
C. Handle on a higher level:
For instance in ASP.NET use the Application_Error event handler method in Global.asax.
All unhandled exceptions end up and can be handled there.
You can only re-throw from inside of a catch block. Think about it; if you're not in a catch block then your program just crashed or the exception was caught at a higher level. It makes no sense to re-throw from outside a catch block.
Wrap your function in a try/catch and re-throw from the catch if needed. Additionally, if all you are doing is re-throwing then there is no point; just let the exception bubble up.
You can't.
From MSDN
A throw statement can be used in the catch block to re-throw the exception, which has been caught by the catch statement.
If you want to preserve the stacktrace, you have to wrap it in InnerException
public static void ManageException(Exception ex, string customErrorMsg, bool displayMessage)
{
...
throw new Exception ("Re-throwing", ex); // You can use your custom Exception object with custom message.
}
Caller of the ManageException should handle ex.InnerException instead of ex.

C# Scope of exception handling

What is the scope of exception handling in C#. I am currently reviewing some code from another programmer on my team and he has a function laid out somewhat like this:
private void function1() {
try {
function2();
}
catch (Exception ex) {
EmailException(ex.message());
}}
private void function2() {
try {
// Do stuff
}
catch (Exception ex) {
// Handle it here
}}
The bulk of the processing code is in function2. However his reporting handling is in function1. Will an exception in function2 kick back to the function1 handler that sends the report?
Edit:
Thanks for your responses, they all were very helpful!
Assuming // Handle it here does not rethrow the exception, function1 will never see the original exception.
It is possible function2 will raise a new issue in its catch though, much like it's possible EmailException could err in function1.
Only if
a) function2 re-throws the original exception with throw or a new exception with throw new ...
b) an unexpected exception occurs inside function2's catch block or after it (which actually in this case is impossible since the catch block is the last thing that happens in function2).
No, an exception propagates only until it is caught.
However, you can re-throw the exception at the end of the catch in function2, leading to the desired behaviour:
private void function2() {
try {
// Do stuff
}
catch (Exception ex) {
// Handle it here
throw; // <- Re-throw the exception.
// Note this is different from `throw ex;`
}
}
Will an exception in function2 kick back to the function1 handler that sends the report?
No unless
An exception occurs outside of function2's try block
An exception occurs inside the function2 exception block
An exception is thrown e.g. trow or trow ex from function2's exception block
An exception is raised in function2's try block that is automatically retrown like ThreadAbortException
In .net, when an exception occurs, the system will search through the nested try blocks on the stack to determine if there is a catch block that can catch the exception. This occurs before any finally blocks run. If there isn't any block that can catch the exception, the system will invoke an "unhandled exception" handler without running any finally blocks.
If the system that does determine that there is a block that can catch the exception, it will start unwinding the stack and run finally blocks associated with inner try blocks until either it has unwound the stack all the way to the catch block it found, or an exception gets thrown in the execution of a finally block. In the latter situation, the previous exception will be abandoned and not processed further; exception handling will start afresh with the newly-thrown exception.
Although there is a semantic difference between wanting to catch an exception, versus merely wanting to act upon it (but let it be regarded as uncaught), there is no clean way to express that distinction in C#; code which catches an exception is expected to resolve it. The best one can do in C# is use a catch (indicating to the system's exception-processing logic to think one is going to catch the exception) and then use a throw, to indicate one doesn't want to resolve it after all (this will occur after inner "finally" blocks have run). In some other languages such as vb.net, it is possible to act upon exceptions, without catching them, before finally blocks run. While there aren't a huge number of cases where a catch and throw is different from capturing an exception without catching it, there are few cases where the distinction matters. If one is using C# and one wishes to avoid being hostile to surrounding code which might want to capture exceptions from inner code before finalizer blocks run, the best approach is probably to write an exception-handling wrapper method written in vb (or have someone else do it), compile it to a DLL, and then use lambdas to feed such a function methods for it to invoke within a suitable try/filter/catch/finally block.

Continue Program execution even after try catch

When I use try, catch blocks, if any exception is throws the program execution is stopped after the catch is handled. But, I need to continue the program execution even if there is exception. Can any one help me how to do it?
If I understand correctly, here's what you're wanting:
try
{
Statement1(); // <-- Exception is thrown in here
Statement2(); // <-- You want to go here after the catch block executes
}
catch
{
HandleException();
}
Try/catch blocks don't work that way. You would have to rewrite your code as follows, instead:
try
{
Statement1();
}
catch
{
}
try
{
Statement2();
}
catch
{
}
Uncaught exceptions terminate execution.
If an exception is caught and not rethrown, the catch() clause is executed, then the finally() clause (if there is one) and execution then continues with the statement following the try/catch/finally block.
If an exception is caught and rethrown, the catch() clause is executed up to and including the throw statement; the finally() clause (if there is one) is executed), then exception is (re-)thrown and the stack unwinding continues.
As the call stack is unwound, finally() clauses are executed as they go out of scope and Dispose() is called as variables declare in using statements go out of scope.
What does not happen is that control does not (and cannot) resume at the point the original exception was thrown. It sounds like you are catching exceptions at a high level -- such as your Main() method -- and expecting execution to continue at original point of failure.
To make that happen, you need to catch the exception at the point at which handling makes contextual sense, and, having handled the exception, either retry the failing operation or ignore the problem.
Doing exception handling well is rather difficult; hence the dictum that the best exception handling practice is to not handle it. Exceptions are supposed to be just that: exceptional. Your code should not throw exception as a normal matter of course; nor should you generally use exceptions as validation technique or as a flow-of-control operator.
If you handle the exception and do not re-throw it (or another Exception) from your catch block, your program should resume.
Additionally, if you are catching exceptions of a certain type (say IO exceptions), but the code in the try block is throwing a different type (say a SQL exception), your catch block with not catch it and the exception will bubble up till the program terminates.
What exactly are you doing in your catch blocks?
If you talking about function (not program) you can use finally to continue your function
try
{
}
catch(MyException ex)
{
}
finally
{
// other code to be done
}
but if you saying program crashes, the cach without any argument can handle it.
If you've reached out to a method that contains your try and catch, you could just do something like this...
//Start Here
exceptionMethod()
//Code will continue here after you've returned from your catch block in exceptionMethod()
doSomeMoreStuff()
exceptionMethod()
try{
doStuff()
}
catch(Exception e){
return
}
a simple return in your catch block should do the trick.

Categories