I have seen people say that it is bad form to use catch with no arguments, especially if that catch doesn't do anything:
StreamReader reader=new StreamReader("myfile.txt");
try
{
int i = 5 / 0;
}
catch // No args, so it will catch any exception
{}
reader.Close();
However, this is considered good form:
StreamReader reader=new StreamReader("myfile.txt");
try
{
int i = 5 / 0;
}
finally // Will execute despite any exception
{
reader.Close();
}
As far as I can tell, the only difference between putting cleanup code in a finally block and putting cleanup code after the try..catch blocks is if you have return statements in your try block (in that case, the cleanup code in finally will run, but code after the try..catch will not).
Otherwise, what's so special about finally?
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.
"Finally" is a statement of "Something you must always do to make sure program state is sane". As such, it's always good form to have one, if there's any possibility that exceptions may throw off the program state. The compiler also goes to great lengths to ensure that your Finally code is run.
"Catch" is a statement of "I can recover from this exception". You should only recover from exceptions you really can correct - catch without arguments says "Hey, I can recover from anything!", which is nearly always untrue.
If it were possible to recover from every exception, then it would really be a semantic quibble, about what you're declaring your intent to be. However, it's not, and almost certainly frames above yours will be better equipped to handle certain exceptions. As such, use finally, get your cleanup code run for free, but still let more knowledgeable handlers deal with the issue.
Because when that one single line throws an exception, you wouldn't know it.
With the first block of code, the exception will simply be absorbed, the program will continue to execute even when the state of the program might be wrong.
With the second block, the exception will be thrown and bubbles up but the reader.Close() is still guaranteed to run.
If an exception is not expected, then don't put a try..catch block just so, it'll be hard to debug later when the program went into a bad state and you don't have an idea why.
Finally is executed no matter what. So, if your try block was successful it will execute, if your try block fails, it will then execute the catch block, and then the finally block.
Also, it's better to try to use the following construct:
using (StreamReader reader=new StreamReader("myfile.txt"))
{
}
As the using statement is automatically wrapped in a try / finally and the stream will be automatically closed. (You will need to put a try / catch around the using statement if you want to actually catch the exception).
While the following 2 code blocks are equivalent, they are not equal.
try
{
int i = 1/0;
}
catch
{
reader.Close();
throw;
}
try
{
int i = 1/0;
}
finally
{
reader.Close();
}
'finally' is intention-revealing code. You declare to the compiler and to other programmers that this code needs to run no matter what.
if you have multiple catch blocks and you have cleanup code, you need finally. Without finally, you would be duplicating your cleanup code in each catch block. (DRY principle)
finally blocks are special. The CLR recognizes and treats code withing a finally block separately from catch blocks, and the CLR goes to great lengths to guarantee that a finally block will always execute. It's not just syntactic sugar from the compiler.
I agree with what seems to be the consensus here - an empty 'catch' is bad because it masks whatever exception might have occurred in the try block.
Also, from a readability standpoint, when I see a 'try' block I assume there will be a corresponding 'catch' statement. If you are only using a 'try' in order to ensure resources are de-allocated in the 'finally' block, you might consider the 'using' statement instead:
using (StreamReader reader = new StreamReader('myfile.txt'))
{
// do stuff here
} // reader.dispose() is called automatically
You can use the 'using' statement with any object that implements IDisposable. The object's dispose() method gets called automatically at the end of the block.
Use Try..Catch..Finally, if your method knows how to handle the exception locally. The Exception occurs in Try, Handled in Catch and after that clean up is done in Finally.
In case if your method doesn't know how to handle the exception but needs a cleanup once it has occurred use Try..Finally
By this the exception is propagated to the calling methods and handled if there are any suitable Catch statements in the calling methods.If there are no exception handlers in the current method or any of the calling methods then the application crashes.
By Try..Finally it is ensured that the local clean up is done before propagating the exception to the calling methods.
The try..finally block will still throw any exceptions that are raised. All finally does is ensure that the cleanup code is run before the exception is thrown.
The try..catch with an empty catch will completely consume any exception and hide the fact that it happened. The reader will be closed, but there's no telling if the correct thing happened. What if your intent was to write i to the file? In this case, you won't make it to that part of the code and myfile.txt will be empty. Do all of the downstream methods handle this properly? When you see the empty file, will you be able to correctly guess that it's empty because an exception was thrown? Better to throw the exception and let it be known that you're doing something wrong.
Another reason is the try..catch done like this is completely incorrect. What you are saying by doing this is, "No matter what happens, I can handle it." What about StackOverflowException, can you clean up after that? What about OutOfMemoryException? In general, you should only handle exceptions that you expect and know how to handle.
If you don't know what exception type to catch or what to do with it, there's no point in having a catch statement. You should just leave it for a higher-up caller that may have more information about the situation to know what to do.
You should still have a finally statement in there in case there is an exception, so that you can clean up resources before that exception is thrown to the caller.
From a readability perspective, it's more explicitly telling future code-readers "this stuff in here is important, it needs to be done no matter what happens." This is good.
Also, empty catch statements tend to have a certain "smell" to them. They might be a sign that developers aren't thinking through the various exceptions that can occur and how to handle them.
Finally is optional -- there's no reason to have a "Finally" block if there are no resources to clean up.
Taken from: here
Raising and catching exceptions should not routinely occur as part of the successful execution of a method. When developing class libraries, client code must be given the opportunity to test for an error condition before undertaking an operation that can result in an exception being raised. For example, System.IO.FileStream provides a CanRead property that can be checked prior to calling the Read method, preventing a potential exception being raised, as illustrated in the following code snippet:
Dim str As Stream = GetStream()
If (str.CanRead) Then
'code to read stream
End If
The decision of whether to check the state of an object prior to invoking a particular method that may raise an exception depends on the expected state of the object. If a FileStream object is created using a file path that should exist and a constructor that should return a file in read mode, checking the CanRead property is not necessary; the inability to read the FileStream would be a violation of the expected behavior of the method calls made, and an exception should be raised. In contrast, if a method is documented as returning a FileStream reference that may or may not be readable, checking the CanRead property before attempting to read data is advisable.
To illustrate the performance impact that using a "run until exception" coding technique can cause, the performance of a cast, which throws an InvalidCastException if the cast fails, is compared to the C# as operator, which returns nulls if a cast fails. The performance of the two techniques is identical for the case where the cast is valid (see Test 8.05), but for the case where the cast is invalid, and using a cast causes an exception, using a cast is 600 times slower than using the as operator (see Test 8.06). The high-performance impact of the exception-throwing technique includes the cost of allocating, throwing, and catching the exception and the cost of subsequent garbage collection of the exception object, which means the instantaneous impact of throwing an exception is not this high. As more exceptions are thrown, frequent garbage collection becomes an issue, so the overall impact of the frequent use of an exception- throwing coding technique will be similar to Test 8.05.
It's bad practice to add a catch clause just to rethrow the exception.
If you'll read C# for programmers you will understand, that the finally block was design to optimize an application and prevent memory leak.
The CLR does not completely eliminate leaks... memory leaks can occur if program inadvertently keep references to unwanted objects
For example when you open a file or database connection, your machine will allocate memory to cater that transaction, and that memory will be kept not unless the disposed or close command was executed. but if during transaction, an error was occurred, the proceeding command will be terminated not unless it was inside the try.. finally.. block.
catch was different from finally in the sense that, catch was design to give you way to handle/manage or interpret the error it self. Think of it as person who tells you "hey i caught some bad guys, what do you want me to do to them?"
while finally was designed to make sure that your resources was properly placed. Think of it of someone that whether or not there is some bad guys he will make sure that your property was still safe.
And you should allow those two to work together for good.
for example:
try
{
StreamReader reader=new StreamReader("myfile.txt");
//do other stuff
}
catch(Exception ex){
// Create log, or show notification
generic.Createlog("Error", ex.message);
}
finally // Will execute despite any exception
{
reader.Close();
}
With finally, you can clean up resources, even if your catch statement throws the exception up to the calling program. With your example containing the empty catch statement, there is little difference. However, if in your catch, you do some processing and throw the error, or even just don't even have a catch at all, the finally will still get run.
Well for one, it's bad practice to catch exceptions you don't bother to handle. Check out Chapter 5 about .Net Performance from Improving .NET Application Performance and Scalability. Side note, you should probably be loading the stream inside the try block, that way, you can catch the pertinent exception if it fails. Creating the stream outside the try block defeats its purpose.
Amongst probably many reasons, exceptions are very slow to execute. You can easily cripple your execution times if this happens a lot.
The problem with try/catch blocks that catch all exceptions is that your program is now in an indeterminate state if an unknown exception occurs. This goes completely against the fail fast rule - you don't want your program to continue if an exception occurs. The above try/catch would even catch OutOfMemoryExceptions, but that is definitely a state that your program will not run in.
Try/finally blocks allow you to execute clean up code while still failing fast. For most circumstances, you only want to catch all exceptions at the global level, so that you can log them, and then exit out.
The effective difference between your examples is negligible as long as no exceptions are thrown.
If, however, an exception is thrown while in the 'try' clause, the first example will swallow it completely. The second example will raise the exception to the next step up the call stack, so the difference in the stated examples is that one completely obscures any exceptions (first example), and the other (second example) retains exception information for potential later handling while still executing the content in the 'finally' clause.
If, for example, you were to put code in the 'catch' clause of the first example that threw an exception (either the one that was initially raised, or a new one), the reader cleanup code would never execute. Finally executes regardless of what happens in the 'catch' clause.
So, the main difference between 'catch' and 'finally' is that the contents of the 'finally' block (with a few rare exceptions) can be considered guaranteed to execute, even in the face of an unexpected exception, while any code following a 'catch' clause (but outside a 'finally' clause) would not carry such a guaranty.
Incidentally, Stream and StreamReader both implement IDisposable, and can be wrapped in a 'using' block. 'Using' blocks are the semantic equivalent of try/finally (no 'catch'), so your example could be more tersely expressed as:
using (StreamReader reader = new StreamReader("myfile.txt"))
{
int i = 5 / 0;
}
...which will close and dispose of the StreamReader instance when it goes out of scope.
Hope this helps.
try {…} catch{} is not always bad. It's not a common pattern, but I do tend to use it when I need to shutdown resources no matter what, like closing a (possibly) open sockets at the end of a thread.
Related
I thought I had understood how exception handling in C# works. Re-reading the documentation for fun and self-confidence, I have run into problems:
This document claims that the following two code snippets are equivalent, even more, that the first one is translated to the latter one at compile time.
using (Font font1 = new Font("Arial", 10.0f)) {
byte charset = font1.GdiCharSet;
}
and
{
Font font1 = new Font("Arial", 10.0f);
try {
byte charset = font1.GdiCharSet;
}
finally {
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
Furthermore, it claims:
The using statement ensures that Dispose is called even if an
exception occurs while you are calling methods on the object.
In contrast, that document states:
Within a handled exception, the associated finally block is guaranteed
to be run. However, if the exception is unhandled, execution of the
finally block is dependent on how the exception unwind operation is
triggered.
I do not get this together. In the code example from the first document, the exception clearly is unhandled (since there is no catch block). Now, if the statement from the second document is true, the finally block is not guaranteed to execute. This ultimately contradicts what the first document says ("The using statement ensures ...") (emphasis mine).
So what is the truth?
EDIT 1
I still don't get it. StevieB's answer has made me read more parts from the C# language specification. In section 16.3, we have:
[...] This search continues until a catch clause is found that can
handle the current exception [...] Once a matching catch clause is
found, the system prepares to transfer control to the first statement
of the catch clause. Before execution of the catch clause begins, the
system first executes, in order, any finally clauses that were
associated with try statements more nested that than the one that
caught the exception.
So have I made a simple test program which contains code which produces a division by zero and is within a try block. That exception is never caught in any of my code, but the respective try statement has a finally block:
int b = 0;
try {
int a = 10 / b;
}
finally {
MessageBox.Show("Hello");
}
Initially, according to the documentation snippet above, I had expected that the finally block never would be executed and that the program just would die when being executed without a debugger attached. But this is not the case; instead, the "exception dialog box" we all know too well is shown, and after that, the "Hello" dialog box appears.
After thinking a while about that and after having read docs, articles and questions like this and that, it became clear that this "exception dialog box" is produced by a standard exception handler which is built into Application.Run() and the other usual methods which could "start" your program, so I am not wondering any more why the finally block is run.
But I am still totally baffled because the "Hello" dialog appears after the "exception dialog box". The documentation snippet above is pretty clear (well, probably I am just too silly again):
The CLR won't find a catch clause which is associated with the try statement where the division by zero happens. So it should pass the exception up one level to the caller, won't find a matching catch clause there as well (there is not even a try statement there) and so on (as noted above, I do not handle (i.e. catch) any exception in this test program).
Finally, the exception should meet the CLR's default catch-all exception handler (i.e. that one which is by default active in Application.Run() and its friends), but (according to the documentation above) the CLR should now execute all finally blocks which are more deeply nested than that default handler ("my" finally block belongs to these, doesn't it?) before executing the CLR catch-all default handler's catch block.
That means that the "Hello" dialog should appear before the "exception dialog box", doesn't it?. Well, obviously, it's the other way around. Could somebody elaborate on that?
This document claims that the following two code snippets are equivalent
They are.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object.
Pretty much.
This ultimately contradicts what the first document says
Well, the first one was being a bit too vague, rather than flat-out incorrect.
There are cases where a finally will not run, including that implied by a using. A StackOverflowException would be one example (a real one from overflowing the stack, if you just do throw new StackOverflowException() the finally will run).
All the examples are things you can't catch, and your application is going down, so if the clean up from using is only important while the application is running, then finally is fine.
If the clean-up is vital even when the program crashes, then finally can never be enough, as it can't deal with e.g. a power plug being pulled out, which in the sort of cases where clean up is vital even in a crash, is a case that needs to be considered.
In any case where the exception is caught further up and the program continues, the finally will run.
With catchable exceptions that aren't caught, then finally blocks will generally run, but there are still some exceptions. One would be if the try-finally was inside a finaliser and the try took a long time; after a while on the finaliser queue the application will just fail-fast.
If your definition of "unhandled exception" (that it must be handled by a catch clause within the same try block) was correct, there would be no reason to ever allow the construct
try {
...
}
finally {
...
}
Since by your definition, the finally block would never run. Since the above construct is valid, we must conclude that your definition of "unhandled exception" is incorrect.
What it means is "if the exception is not handled by any exception handler, anywhere in the call stack".
You have to give the documentation a little leeway. In most circumstances there's an implied "within reason". For example, if I turn my computer off none of those finally blocks or using/Disposes will be called.
Apart from the computer shutting off, there are a handful of circumstances that OS can terminate your application--effectively shutting it off. In these circumstances Dispose and finally won't be invoked. Those are usually pretty serious error conditions like out of stack or out of memory. There are some complex scenarios where that can happen with less-than-exceptional-exceptions. For example, if you have native code that creates a managed object on a background thread and that managed object and something on that thread throws an native exception, it's likely that the managed exception handlers won't get called (e.g. Dispose) because the OS will just terminate the thread and anything that could have been disposed is not accessible any more.
But, yes, those statements are effectively equivalent and within reason the finally block will be executed and Dispose will be called.
The C# language specification states that the finally blocks will be executed (be that in a using statement or elsewhere) for System.Exception or any of its derived exceptions. Of course, if you get an exception that can't be handled with the usual try..catch logic e.g. AccessViolationException all bets are off which is where the ambiguity comes in.
The spec is installed with Visual Studio 2013 and later - with 2017 it's in C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC#\Specifications\1033
In section
8.9.5 The throw statement
we see the following:
When an exception is thrown, control is transferred
to the first catch clause in an enclosing try statement that can
handle the exception. The process that takes place from the point of
the exception being thrown to the point of transferring control to a
suitable exception handler is known as exception propagation.
Propagation of an exception consists of repeatedly evaluating the
following steps until a catch clause that matches the exception is
found. In this description, the throw point is initially the location
at which the exception is thrown.
In the current function member,
each try statement that encloses the throw point is examined. For each
statement S, starting with the innermost try statement and ending with
the outermost try statement, the following steps are evaluated:
If
the try block of S encloses the throw point and if S has one or more
catch clauses, the catch clauses are examined in order of appearance
to locate a suitable handler for the exception. The first catch clause
that specifies the exception type or a base type of the exception type
is considered a match. A general catch clause (§8.10) is considered a
match for any exception type. If a matching catch clause is located,
the exception propagation is completed by transferring control to the
block of that catch clause.
Otherwise, if the try block or a catch
block of S encloses the throw point and if S has a finally block,
control is transferred to the finally block. If the finally block
throws another exception, processing of the current exception is
terminated. Otherwise, when control reaches the end point of the
finally block, processing of the current exception is continued.
If
an exception handler was not located in the current function
invocation, the function invocation is terminated, and one of the
following occurs:
If the current function is non-async, the steps
above are repeated for the caller of the function with a throw point
corresponding to the statement from which the function member was
invoked.
If the current function is async and task-returning, the
exception is recorded in the return task, which is put into a faulted
or cancelled state as described in §10.14.1.
If the current function
is async and void-returning, the synchronization context of the
current thread is notified as described in §10.14.2.
If the
exception processing terminates all function member invocations in the
current thread, indicating that the thread has no handler for the
exception, then the thread is itself terminated. The impact of such
termination is implementation-defined.
I believe (correct me if I am wrong) the answer is lying in the definition:
The using statement ensures that Dispose is called even if an
exception occurs while you are calling methods on the object.
So if any exceptions occur in any methods called by the object of using, finally is ensured to run. On the other hand finally is not guaranteed to run if inside the using block call other methods not related with the object cause an exception
First of all, I would like to bring to your notice that using statement cannot be used for all types. This can be used only for types that implement IDisposable interface which has a functionality to dispose the object automatically. This is present in the second document you mentioned
C# also contains the using statement, which provides similar functionality for IDisposable objects in a convenient syntax.
This means if an unhandled exception happens, cleaning up of your objects is handled by the Dispose() method of the type(this is given for using statement documentation)
Coming to the query, even though your finally block(generated) is not guarenteed to run for unhandled exceptions, the object dispose operation is handled during runtime by .Net CLR
Hope this clears your doubt
I have a method doSomething() that has one try catch block, within which I call another method.
public void doSomething()
{
try
{
doSomethingElse();
}
catch
{
// catch implementation goes here
}
}
In that other method doSomethingElse() I don't have any try catch block. I am depending on the main method's try-catch to handle the exception. If there are any exceptions in doSomethingElse() they will be bubbled up to the method doSomething's try-catch block.
Is there anything wrong with this approach?
Thanks for your time.
This is perfectly legitimate.
Let exceptions bubble up to where you can/know what to do with them.
It is good practice not to litter your code with try/catch blocks that don't add anything.
However, having empty catch blocks is bad practice (though I am assuming the code you have posted is a simplified version omitting the catch block code).
Nothing wrong with that.
As others have said, don't swallow exceptions. It may also be a good idea not to throw a new exception; rather, just catch (Exception) and throw it. Of course, it should also be noted to try and be specific with exceptions, and not just use the default Exception.
It's smelly. Catching an exception requires that you restore the program state, as though doSomethingElse() was never called. It very much depends on what the method does but it is generally pretty unusual to write a method without any side effects whatsoever. If it has any then those side effects need to be canceled. Only doSomethingElse() can do so, the doSomething() method is powerless to guess how many of those side effects were actually executed. And can thus not reliably restore state.
This is especially the case when you catch all exceptions. You'll grab the nasty ones as well. Like AccessViolation or FatalExecutionEngineError, exceptions that leave the CLR itself in a unknown state, you can never restore that. What happens next is quite unpredictable. You'll get a flurry of additional exceptions only if you're lucky. Diagnosing them is impossible, you threw away valuable info.
This is ok, but you forget about ; after doSomethingElse()
I'm in the process of thrashing through the whole exception-handling jungle, and I'm now trying to determine just how many try/catch blocks I need, and where to put them.
From my controller I have
CreateInvitation(fromUser, toUser);
which calls down to my BLL method
public static Invitation CreateInvitaton(User fromUser, User toUser)
{
try
{// see if toUser exists, then create the invitation}
catch
{// throw something, maybe?}
}
Do I actually need to re-throw it in that method? Won't it go back up the stack even if I don't re-throw it?
Do I need to wrap the controller's call in a try/catch block too, or is that redundant?
Maybe I don't need the try/catch block in the BLL method at all, and only need a try/catch block in my controller?
I'm looking at quite a few possible combinations here, and have no idea what the proper one is.
Thanks.
The exception handler, as written in your example, is doing absolutely nothing. (well, it's wasting a little bit of time, but it's doing nothing of use)
Had it been:
try
{...}
catch
{
// do something here.
throw;
}
Then the try/catch & throw would be needed.
Catch exceptions locally if and only if they indicate exceptional behaviour and can be fixed (or commented) locally.
Hard enough to find an example - here's one: I have some objects which need pessimistic lock. The lock is needed because writing to the object from the web application while another (background) app is reading it could lead to disaster. It is truly an exception, because it will happen very rarely. Moreover, I can do nothing about it beforehand (because the lock might have been acquired just before the next line is executed). However, I can retry in a few msecs, because I know chances are good the object is released again. Still, all this does not happen in the controller, but in a service class.
Don't use exceptions for expected conditions (invalid input, for example).
Also, I agree most exceptions in web applications cannot be handled except for logging a message (which should not be done in the controllers) and sending an error page. Lastly, when catching exceptions, make sure to do it right (catch a specific exception type, retrow with throw; not throw ex;)
I'm writing a custom class in C# and I'm throwing a couple exceptions if people give the wrong inputs in some of the methods. If the exception is thrown, will any of the code in the method after the throw still be executed? Do I have to put a break after the throw, or does a throw always quit the method?
When you throw an exception, the next code to get executed is any catch block that covers that throw within the method (if any) then, the finally block (if any). You can have a try, a try-catch, a try-catch-finally or a try-finally. Then, if the exception is not handled, re-thrown by a catch block or not caught at all, control is returned to the caller. For example, you will get "Yes1, Yes2, Yes3" from this code ...
try
{
Console.WriteLine("Yes1");
throw (new Exception());
Console.WriteLine("No1");
}
catch
{
Console.WriteLine("Yes2");
throw;
Console.WriteLine("No2");
}
finally
{
Console.WriteLine("Yes3");
}
Console.WriteLine("No3");
Throw will move up the stack, thus exiting the method.
I recommend stepping through your program with a debugger then you'll see for yourself what is going on. Very useful for learning!
I came here looking for an answer to the original post and almost missed a very valuable answer posted by Eric Lippert. Here's his answer posted in the comments:
Split this up into three questions.
(1) Will any of the code in the method after the throw be executed?
YES. If the exception was inside a try then code inside matching catch blocks or finally block will be executed. If there is no try block then NO. Control branches to the nearest enclosing finally, catch or (in vb) exception filter block up the stack.
(2) Do I have to put a break after the throw?
NO, never do that. The end point of the throw statement is not reachable; a throw is treated as a goto by the compiler. A statement immediately following a throw is not reachable and will never execute.
(3) Does a throw always quit the method?
NO. If the throw is in a try and the try has a matching catch block then the catch block can "eat" the exception. Only if there is no catch block does the exception do a non-local goto up the call stack.
If you have more questions about this, I recommend reading the C# specification; all this behavior is clearly documented.
Finally, it sounds like you are throwing "boneheaded" exceptions, as in "hey boneheaded caller, I told you to never give me that data". That's great because it prevents bugs in callers. But if you do that, you should make sure that the caller has some way of knowing what you expect! If the caller cannot figure out whether you're going to throw or not based on your documentation, then you haven't made a boneheaded exception, you've made a vexing exception. See http://blogs.msdn.com/ericlippert/archive/2008/09/10/vexing-exceptions.aspx for details.
If you've wrapped your code in a Try...Catch...Finally block, then the code under Finally will always execute. For example:
Try
' do some stuff here
' Examine user input
If user input isn't valid
Throw new exception
Catch
Throw ' Just re-throws the same exception
Finally
' This code will execute, no matter what - exception or not
End Try
As an aside to your actual question: you might want to rethink using exceptions to provide validation info back to the user.
Raising exceptions is expensive resource-wise and slow. If you have a number of validation rules that you need to apply then write specific code for these - you should probably only rely on exception handling for things you don't anticipate.
When writing a C# application whose #1 priority is to never crash, how often should I used a try-catch block?
Can I encapsulate all the statements in a method in try-catch blocks?
public void SomeMethod()
{
try
{
// entire contents of the function
// library calls
// function calls
// variable initialization .. etc
}
catch (Exception e)
{
// recover
}
}
What are the downsides to wrapping everything in try-catch blocks?
The only down side is when an exception is actually thrown. There is no overhead for wrapping the code, except for when exceptions occur.
Also, you don't want to use try/catch for control flow. Consider this (bad code):
try {
FileStream fs = File.Open("somefile.txt", FileMode.Open);
} catch (Exception ex) {
MessageBox.Show("The file does not exist. Please select another file");
}
You'll get more performance from some thing like File.Exists. such as:
if(!File.Exists("somefile.txt"))
MessageBox.Show("The file does not exist.")
EDIT:
found the MSDN direct quote:
Finding and designing away
exception-heavy code can result in a
decent perf win. Bear in mind that
this has nothing to do with try/catch
blocks: you only incur the cost when
the actual exception is thrown. You
can use as many try/catch blocks as
you want. Using exceptions
gratuitously is where you lose
performance. For example, you should
stay away from things like using
exceptions for control flow.
This is a big topic. Start here for some excellent discussion of Exception handling best practices and be prepared for a religious war...
Code Analysis Team Blog
Martin Fowler - Fail Fast
MSDN on Exception Handling
Checked vs Unchecked Exceptions
My own opinion is that for the most part you use "try/finally" a lot, but "catch" very little. The problem is that if you attempt to catch and handle Exceptions in the wrong instances, you may inadvertently put your application in a bad state. As a rule, use dev and test to learn where you actually need to handle an exception. Those will be places that you can't check. i.e. you shouldn't really need to handle nullreference or filenotfound because you can proactively check for those. Only exceptions you know may happen, but you can't do anything about. Beyond that, for the sake of your data's state, let it crash.
If you are swallowing exceptions, it generally means you don't understand your program or why you are getting an exception. Catching System.Exception is the poster child of code smells...
Actually, I very rarely use a catch block except for logging purposes. finally is much more common for me. Most times, lock or using do everything I can usefully do (and indeed, that is a finally also).
Eric Lippert has a blog entry on exceptions that may be useful.
The key to this question is the following line:
// recover
To be able to recover, you have to know what and how to recover. And that's assuming it is possible to recover, which quite frequently it isn't.
You should only use the catch part of try/catch/finally to swallow an exception when you know how to handle the exception, when you know how to recover from it, and when you're sure you can do so without leaving the application in an inconsistent or invalid state.
If you can do this for all possible exceptions in all method calls in your application then go right ahead, otherwise you might need to re-think your #1 priority (sometimes failing fast is a better options than trying to keep an application alive when something has gone wrong, and having a much harder to debug crash later on).
Generally IMO it is better to put smaller chunks that are out of your control in a try catch. If you say:
try
{
//anything that could possibly go wrong
//This kind of thing is only good for Logging IMO and could be done in
//Global.asax
}
How could you possibly know what to do in your catch method cause it could be anything...
Its much better to go:
try
{
//divide user imputs
}
catch(DivideByZeroException)
{
// tell user bad inputs ect....
}
catch (Exception e)
{
//If you choose to throw the exception you should
//***********************
throw;
//VS
throw ex; //Throw ex will restart the stack trace
// recover
}
finally
{
//Clean up resources and continue
}
In which finally is always run
There is performance overhead for try blocks, if you do that your entire function will run slower then it otherwise would. catch (Exception e) is also a bad idea, if you catch you want to do something useful with what you caught, and if you catch all exceptions it is impossible to know what you should be doing.
You can do this, although almost in any given environment you're running in, there's a global exception handler where you can catch and handle even unknown errors.
For web apps, there's the Global.asax, for a console program, just wrap your Main() in a try/catch, for services, there's AppDomain.CurrentDomain.UnhandledException, etc.
You should wrap sections where you can predict what the exception might be in more specific blocks, but the global exception handlers should greatly simplify your code and help you out.
You should only catch and stop the exception without rethrowing it if you can meaningfully handle it. Otherwise it is an error and it should propagate up.
I assume that when they say "this app should never crash" there is an implicit requirement that it behaves correctly. Only stoping exceptions that are meaningfully handled satisfies the behaving correctly requirement.
Typically an app will have a single top-level catch block to catch and log unhandled exceptions. These should occur infrequently (and perhaps your requirement can be interpreted to mean these should not happen at all). If you catch and stop exceptions anywhere else in your code, you risk not discovering these problems. If you catch log and stop in lots of other parts of your code, you have a poorly constructed app from the perspective of separation-of-concerns.
I try to avoid try catch blocks generally. I prefer to use blocks to force the user into obeying the rules of an application. For example, if a user should only enter an int that is equal to or less than an int x I'd use:
if (input > x)
{
Console.WriteLine("Invalid input. Please enter a number that is equal to or less than x.");
{...}
}
rather than using:
catch (IndexOutOfRangeException)
{
//error message here
}
From my own personal experience I find it easier to write as you can avoid encapsulating code in a try block (guarding code).
Of course, there will always be times where using try catch is unavoidable - I just like to work around it where possible.
Our current application has a similar mandate: Never crash. Always back out gracefully. To do this, you have to make sure that every line of code is either enclosed in a try-catch block or only called by code that its exceptions can bubble up into.
Also, to protect against uncaught exceptions, we attach an UnhandledExceptionEventHandler to AppDomain.CurrentDomain.
You should use them anytime a piece of code can thrown an exception.
You have to be careful, catching general exceptions is never a good idea. You have to decide which layer you want to handle them.
Meaning the deeper you are you want to catch very specific excpetion and go more general. In a database catch the SqlException. As you go higher in the stack you catch more exceptions to finally catching the general exception at the very top.
That way you can deal with each exception on a case by case basis. A general exception you aren't going to know what to do with.
public void functionName
{
try
{
//your codes
//sometimes 'return' shows exceptions
}
catch(Exception e)
{
messagebox.show(e.Tostring()); //to know what is the exception
}
finally
{
}
}
try catch in c#:
try{
}
catch (NullReferenceException en)
{
}