Are these try/catch'es equivalent? - c#

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

Related

What is the purpose of using the following try-catch block? c# [duplicate]

I'm looking at the article C# - Data Transfer Object on serializable DTOs.
The article includes this piece of code:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
throw ex;
}
}
The rest of the article looks sane and reasonable (to a noob), but that try-catch-throw throws a WtfException... Isn't this exactly equivalent to not handling exceptions at all?
Ergo:
public static string SerializeDTO(DTO dto) {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
Or am I missing something fundamental about error handling in C#? It's pretty much the same as Java (minus checked exceptions), isn't it? ... That is, they both refined C++.
The Stack Overflow question The difference between re-throwing parameter-less catch and not doing anything? seems to support my contention that try-catch-throw is-a no-op.
EDIT:
Just to summarise for anyone who finds this thread in future...
DO NOT
try {
// Do stuff that might throw an exception
}
catch (Exception e) {
throw e; // This destroys the strack trace information!
}
The stack trace information can be crucial to identifying the root cause of the problem!
DO
try {
// Do stuff that might throw an exception
}
catch (SqlException e) {
// Log it
if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound.
// Do special cleanup, like maybe closing the "dirty" database connection.
throw; // This preserves the stack trace
}
}
catch (IOException e) {
// Log it
throw;
}
catch (Exception e) {
// Log it
throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java).
}
finally {
// Normal clean goes here (like closing open files).
}
Catch the more specific exceptions before the less specific ones (just like Java).
References:
MSDN - Exception Handling
MSDN - try-catch (C# Reference)
First, the way that the code in the article does it is evil. throw ex will reset the call stack in the exception to the point where this throw statement is losing the information about where the exception actually was created.
Second, if you just catch and re-throw like that, I see no added value. The code example above would be just as good (or, given the throw ex bit, even better) without the try-catch.
However, there are cases where you might want to catch and rethrow an exception. Logging could be one of them:
try
{
// code that may throw exceptions
}
catch(Exception ex)
{
// add error logging here
throw;
}
Don't do this,
try
{
...
}
catch(Exception ex)
{
throw ex;
}
You'll lose the stack trace information...
Either do,
try { ... }
catch { throw; }
OR
try { ... }
catch (Exception ex)
{
throw new Exception("My Custom Error Message", ex);
}
One of the reason you might want to rethrow is if you're handling different exceptions, for
e.g.
try
{
...
}
catch(SQLException sex)
{
//Do Custom Logging
//Don't throw exception - swallow it here
}
catch(OtherException oex)
{
//Do something else
throw new WrappedException("Other Exception occured");
}
catch
{
System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack");
throw; //Chuck everything else back up the stack
}
C# (before C# 6) doesn't support CIL "filtered exceptions", which VB does, so in C# 1-5 one reason for re-throwing an exception is that you don't have enough information at the time of catch() to determine whether you wanted to actually catch the exception.
For example, in VB you can do
Try
..
Catch Ex As MyException When Ex.ErrorCode = 123
..
End Try
...which would not handle MyExceptions with different ErrorCode values. In C# prior to v6, you would have to catch and re-throw the MyException if the ErrorCode was not 123:
try
{
...
}
catch(MyException ex)
{
if (ex.ErrorCode != 123) throw;
...
}
Since C# 6.0 you can filter just like with VB:
try
{
// Do stuff
}
catch (Exception e) when (e.ErrorCode == 123456) // filter
{
// Handle, other exceptions will be left alone and bubble up
}
My main reason for having code like:
try
{
//Some code
}
catch (Exception e)
{
throw;
}
is so I can have a breakpoint in the catch, that has an instantiated exception object. I do this a lot while developing/debugging. Of course, the compiler gives me a warning on all the unused e's, and ideally they should be removed before a release build.
They are nice during debugging though.
A valid reason for rethrowing exceptions can be that you want to add information to the exception, or perhaps wrap the original exception in one of your own making:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
string message =
String.Format("Something went wrong serializing DTO {0}", DTO);
throw new MyLibraryException(message, ex);
}
}
Isn't this exactly equivalent to not
handling exceptions at all?
Not exactly, it isn't the same. It resets the exception's stacktrace.
Though I agree that this probably is a mistake, and thus an example of bad code.
You don't want to throw ex - as this will lose the call stack. See Exception Handling (MSDN).
And yes, the try...catch is doing nothing useful (apart from lose the call stack - so it's actually worse - unless for some reason you didn't want to expose this information).
This can be useful when your programming functions for a library or dll.
This rethrow structure can be used to purposefully reset the call stack so that instead of seeing the exception thrown from an individual function inside the function, you get the exception from the function itself.
I think this is just used so that the thrown exceptions are cleaner and don't go into the "roots" of the library.
A point that people haven't mentioned is that while .NET languages don't really make a proper distinction, the question of whether one should take action when an exception occurs, and whether one will resolve it, are actually distinct questions. There are many cases where one should take action based upon exceptions one has no hope of resolving, and there are some cases where all that is necessary to "resolve" an exception is to unwind the stack to a certain point--no further action required.
Because of the common wisdom that one should only "catch" things one can "handle", a lot of code which should take action when exceptions occur, doesn't. For example, a lot of code will acquire a lock, put the guarded object "temporarily" into a state which violates its invariants, then put it object into a legitimate state, and then release the lock back before anyone else can see the object. If an exception occurs while the object is in a dangerously-invalid state, common practice is to release the lock with the object still in that state. A much better pattern would be to have an exception that occurs while the object is in a "dangerous" condition expressly invalidate the lock so any future attempt to acquire it will immediately fail. Consistent use of such a pattern would greatly improve the safety of so-called "Pokemon" exception handling, which IMHO gets a bad reputation primarily because of code which allows exceptions to percolate up without taking appropriate action first.
In most .NET languages, the only way for code to take action based upon an exception is to catch it (even though it knows it's not going to resolve the exception), perform the action in question and then re-throw). Another possible approach if code doesn't care about what exception is thrown is to use an ok flag with a try/finally block; set the ok flag to false before the block, and to true before the block exits, and before any return that's within the block. Then, within finally, assume that if ok isn't set, an exception must have occurred. Such an approach is semantically better than a catch/throw, but is ugly and is less maintainable than it should be.
While many of the other answers provide good examples of why you might want to catch an rethrow an exception, no one seems to have mentioned a 'finally' scenario.
An example of this is where you have a method in which you set the cursor (for example to a wait cursor), the method has several exit points (e.g. if () return;) and you want to ensure the cursor is reset at the end of the method.
To do this you can wrap all of the code in a try/catch/finally. In the finally set the cursor back to the right cursor. So that you don't bury any valid exceptions, rethrow it in the catch.
try
{
Cursor.Current = Cursors.WaitCursor;
// Test something
if (testResult) return;
// Do something else
}
catch
{
throw;
}
finally
{
Cursor.Current = Cursors.Default;
}
One possible reason to catch-throw is to disable any exception filters deeper up the stack from filtering down (random old link). But of course, if that was the intention, there would be a comment there saying so.
It depends what you are doing in the catch block, and if you are wanting to pass the error on to the calling code or not.
You might say Catch io.FileNotFoundExeption ex and then use an alternative file path or some such, but still throw the error on.
Also doing Throw instead of Throw Ex allows you to keep the full stack trace. Throw ex restarts the stack trace from the throw statement (I hope that makes sense).
In the example in the code you have posted there is, in fact, no point in catching the exception as there is nothing done on the catch it is just re-thown, in fact it does more harm than good as the call stack is lost.
You would, however catch an exception to do some logic (for example closing sql connection of file lock, or just some logging) in the event of an exception the throw it back to the calling code to deal with. This would be more common in a business layer than front end code as you may want the coder implementing your business layer to handle the exception.
To re-iterate though the There is NO point in catching the exception in the example you posted. DON'T do it like that!
Sorry, but many examples as "improved design" still smell horribly or can be extremely misleading. Having try { } catch { log; throw } is just utterly pointless. Exception logging should be done in central place inside the application. exceptions bubble up the stacktrace anyway, why not log them somewhere up and close to the borders of the system?
Caution should be used when you serialize your context (i.e. DTO in one given example) just into the log message. It can easily contain sensitive information one might not want to reach the hands of all the people who can access the log files. And if you don't add any new information to the exception, I really don't see the point of exception wrapping. Good old Java has some point for that, it requires caller to know what kind of exceptions one should expect then calling the code. Since you don't have this in .NET, wrapping doesn't do any good on at least 80% of the cases I've seen.
In addition to what the others have said, see my answer to a related question which shows that catching and rethrowing is not a no-op (it's in VB, but some of the code could be C# invoked from VB).
Most of answers talking about scenario catch-log-rethrow.
Instead of writing it in your code consider to use AOP, in particular Postsharp.Diagnostic.Toolkit with OnExceptionOptions IncludeParameterValue and
IncludeThisArgument
Rethrowing exceptions via throw is useful when you don't have a particular code to handle current exceptions, or in cases when you have a logic to handle specific error cases but want to skip all others.
Example:
string numberText = "";
try
{
Console.Write("Enter an integer: ");
numberText = Console.ReadLine();
var result = int.Parse(numberText);
Console.WriteLine("You entered {0}", result);
}
catch (FormatException)
{
if (numberText.ToLowerInvariant() == "nothing")
{
Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}
else
{
throw;
}
}
finally
{
Console.WriteLine("Freed some resources.");
}
Console.ReadKey();
However, there is also another way of doing this, using conditional clauses in catch blocks:
string numberText = "";
try
{
Console.Write("Enter an integer: ");
numberText = Console.ReadLine();
var result = int.Parse(numberText);
Console.WriteLine("You entered {0}", result);
}
catch (FormatException) when (numberText.ToLowerInvariant() == "nothing")
{
Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}
finally
{
Console.WriteLine("Freed some resources.");
}
Console.ReadKey();
This mechanism is more efficient than re-throwing an exception because
of the .NET runtime doesn’t have to rebuild the exception object
before re-throwing it.

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.

Catch Block Choices

I am reading C# article.It suggests that
At the end of the catch block, you have three choices:
• Re-throw the same exception, notifying code higher up in the call stack of the
exception.
• Throw a different exception, giving richer exception information to code higher up in
the call stack.
• Let the thread fall out of the bottom of the catch block.
I am unable to understand the points.It would be a great help, if you clarify it by giving simple example.
Thanks in advance.
Update :
When i need to handle rethrown exception ,do i need to have nested try .. catch blocks like
try
{
try
{
}
catch(InvalidOperationException exp)
{
throw;
}
}
catch(Exception ex)
{
// handle the exception thrown by inner catch block
// (in this case the "throw" clause inside the inner "catch")
}
}
Well, here are those different options in code:
Option 1: Rethrow
try
{
// Something
}
catch (IOException e)
{
// Do some logging first
throw;
}
Option 2: Throw a different exception
try
{
// Something
}
catch (IOException e)
{
// Do some logging first
throw new SorryDaveICantDoThatException("Oops", e);
}
Option 3: Let the thread fall out of the bottom
try
{
// Something
}
catch (IOException e)
{
// Possibly do some logging, and handle the problem.
// No need to throw, I've handled it
}
EDIT: To answer the extra question, yes - if you need to handle a rethrown exception, that needs to be handled in an outer scope, exactly as shown in the question. That's very rarely a good idea though. Indeed, catch blocks should relatively rare in the first place, and nested ones even more so.
These are the choices. Difference between 1 and 2 is that if an exception is thrown and you want to debug to the position is it thrown, you will get there with option 1
(all the way down in the try block at the specific object). With option 2 you will and up only at that line (throw new Exception2())
3 is when you want to ignore the exception and just continue
//1
catch (Exception ex)
{
throw;
}
//2
catch (Exception ex)
{
throw new Exception2();
}
//3
catch (Exception ex)
{
}
return something;
In most production systems the last thing you want is a truly unhandled exception. This is why you typically try and catch statements.
You might be wondering why you would want to throw an error you've caught, and here are a few real world examples.
You've caught an exception in a WCF Application, logged the exception, then thrown a faultException instead to be returned to the WCF client. In the same way you might have a traditional asmx, caught an exception, then thrown a SOAP exception back to the client. Point is certain exceptions need to abide by certain rules: a standard .net exception would not be digested well by a WCF client for example.
You've caught an exception somewhere deep inside your code, logged the exception and possibly even taken some action. But higher up in your code you have another routine that is also waiting for exceptions, at this point higher up, an exception could easily change the business workflow. By catching the exception lower down, the code higher up is not aware of any exception, so you need to throw the exception back out to be caught higher up, so that the code you wrote up there can adjust the workflow. Ofc none of this happens by magic, it all has to be coded, and differant programmers use differant techniques.
You might also want to catch an exception around just 1 or a few statements, for example getting a configuration value from an XML file, if something goes wrong, .net might just return object reference not set. You might catch this, then rethrow the exception as "Configuration Value : Customer Name not provided".
Hope this helps.
rethrow the same exception:
try
{
// do something that raises an exception
}
catch (SomeException ex)
{
// do something with ex
throw;
}
throw a different exception
try
{
// do something that raises an exception
}
catch (SomeException ex)
{
// do something with ex
throw new SomeOtherException(ex); // NOTE: please keep ex as an inner exception
}
let the thread fall out:
try
{
// do something that raises an exception
}
catch (SomeException ex)
{
// do something with ex
}
// the code will finish handling the exception and continue on here
1) Re-throw
try
{
...
}
catch (Exception e)
{
...
throw;
}
2) Throw a new exception
try
{
...
}
catch (Exception e)
{
...
throw new NewException("new exception", e);
}
3) Fall out
try
{
...
}
catch (Exception e)
{
...
}
You could also return in the catch block, so there is that 4th option. Return false, return null, etc... (even return a default value.)
Letting the catch block fall through implies that you have successfully dealt with the Exception that was raised in your try block. If you haven't, better rethrow, or fail in some other way.
this isn't c# specific, it's true of any programming language (call them exceptions, call them errors, call them whatever you want).
So, the answer to you question is that this is a basic premise of all programming and you must determine the correct action to take in your code, given the error, the circumstance and the requirements.
Taylor,
As you are learning about Exception handling I would like to add my 2 cents. Exception throwing is very expensive ( expensive being memory hogging of course ) so in this case you should consider assigning the error message to a string and carry it forward through the application to the log or something.
for example:
string errorMessage = string.empty;
try
{
...
}
catch(Exception e)
{
errorMessage = e.Message + e.StackTrace;;
}
This way you can carry this string anyway. This string can be a global property and can be emailed or logged in text file.
I think that there is something to add to the great answers we've already got here.
It may be part of your overall architectural design (or not) but what I've always observed is that you typically only catch where you can add value (or recover from the error) - in other words, not to try...catch...re-throw multiple times for a single operation.
You should normally plan a consistent pattern or design for how you handle exceptions as part of your overall design. You should always plan to handle exceptions in any case, unhandled exceptions are ugly!

The difference between re-throwing parameter-less catch and not doing anything?

Suppose I have the following two classes in two different assemblies:
//in assembly A
public class TypeA {
// Constructor omitted
public void MethodA
{
try {
//do something
}
catch {
throw;
}
}
}
//in assembly B
public class TypeB {
public void MethodB
{
try {
TypeA a = new TypeA();
a.MethodA();
}
catch (Exception e)
//Handle exception
}
}
}
In this case, the try-catch in MethodA just elevates the exception but doesn't really handle it. Is there any advantage in using try-catch at all in MethodA? In other words, is there a difference between this kind of try-catch block and not using one at all?
In your example, there is no advantage to this. But there are cases where it is desirable to just bubble up a specific exception.
public void Foo()
{
try
{
// Some service adapter code
// A call to the service
}
catch (ServiceBoundaryException)
{
throw;
}
catch (Exception ex)
{
throw new AdapterBoundaryException("some message", ex);
}
}
This allows you to easily identify which boundary an exception occurred in. In this case, you would need to ensure your boundary exceptions are only thrown for code specific to the boundary.
Yes there is a difference. When you catch an exception, .NET assumes you are going to handle it in some way, the stack is unwound up to the function that is doing the catch.
If you don't catch it will end up as an unhandled exception, which will invoke some kind of diagnostic (like a debugger or a exception logger), the full stack and its state at the actual point of failure will be available for inspection.
So if you catch then re-throw an exception that isn't handled elsewhere you rob the diagnostic tool of the really useful info about what actually happened.
With the code the way you've written it for MethodA, there is no difference. All it will do is eat up processor cycles. However there can be an advantage to writing code this way if there is a resource you must free. For example
Resource r = GetSomeResource();
try {
// Do Something
} catch {
FreeSomeResource();
throw;
}
FreeSomeResource();
However there is no real point in doing it this way. It would be much better to just use a finally block instead.
Just rethrowing makes no sense - it's the same as if you did not do anything.
However it gets useful when you actually do something - most common thing is to log the exception. You can also change state of your class, whatever.
Taken as-is, the first option would seem like a bad (or should that be 'useless'?) idea. However, it is rarely done this way. Exceptions are re-thrown from within a Catch block usually under two conditions :
a. You want to check the exception generated for data and conditionally bubble it up the stack.
try
{
//do something
}
catch (Exception ex)
{
//Check ex for certain conditions.
if (ex.Message = "Something bad")
throw ex;
else
//Handle the exception here itself.
}
b. An unacceptable condition has occurred within a component and this information needs to be communicated to the calling code (usually by appending some other useful information or wrapping it in another exception type altogether).
try
{
//do something
}
catch (StackOverflowException ex)
{
//Bubble up the exception to calling code
//by wrapping it up in a custom exception.
throw new MyEuphemisticException(ex, "Something not-so-good just happened!");
}
Never do option A. As Anton says, it eats up the stack trace. JaredPar's example also eats up the stacktrace. A better solution would be:
SomeType* pValue = GetValue();
try {
// Do Something
} finally {
delete pValue;
}
If you got something in C# that needs to be released, for instance a FileStream you got the following two choices:
FileStream stream;
try
{
stream = new FileStream("C:\\afile.txt");
// do something with the stream
}
finally
{
// Will always close the stream, even if there are an exception
stream.Close();
}
Or more cleanly:
using (FileStream stream = new FileStream("c:\\afile.txt"))
{
// do something with the stream
}
Using statement will Dispose (and close) the stream when done or when an exception is closed.
When you catch and throw, it allows you to set a breakpoint on the throw line.
Re-throwing exceptions can be used to encapsulate it into generic exception like... consider following example.
public class XmlException: Exception{
....
}
public class XmlParser{
public void Parse()
{
try{
....
}
catch(IOException ex)
{
throw new XmlException("IO Error while Parsing", ex );
}
}
}
This gives benefit over categorizing exceptions. This is how aspx file handlers and many other system code does exception encapsulation which determines their way up to the stack and their flow of logic.
The assembly A - try catch - block does not make any sense to me. I believe that if you are not going to handle the exception, then why are you catching those exceptions.. It would be anyway thrown to the next level.
But, if you are creating a middle layer API or something like that and handling an exception ( and hence eating up the exception) in that layer does not make sense, then you can throw your own layer ApplicationException. But certainly rethrowing the same exception does not make sense.
Since the classes are in 2 different assemblies, you may want o simply catch the exception for logging it and then throw it back out to the caller, so that it can handle it the way it sees fit. A throw instead of a throw ex will preserve contextual information about where the exception originated. This can prove useful when your assembly is an API/framework where in you should never swallow exceptions unless its meaningful to do so but helpful nonetheless in trouble shooting if it's logged for example to the EventLog.
You can use try{} catch(ex){} block in Method A only if you could catch the specific exception which can be handled in MethodA() (for eg: logging ).
Another option is chain the exception using the InnerException property and pass it to the caller. This idea will not kill the stack trace.

Categories