I recently implemented a function which logs object contents using JSON.SerializeObject.
To cut a long story short, the idea was, that this function would be used in our newly implemented logging mechanism, to track objects when needed, based on system parameterization.
One absolute requirement for the entire logging mechanism, was that it should never throw exceptions, because it would be used extensively. Any developer should be able to use it and under no circumstances should this function cause any interruption in code flow. In case of failure, any call should simply be skipped.
After implementing it and having inspected and handled every exception that I could think of, I decided to wrap the entire functionality in an outer try-catch block, just in case.
Like so:
public static void TrackObject(object obj)
{
try { Console.WriteLine(JsonConvert.SerializeObject(obj)); }
catch { Console.WriteLine("Failed to track object."); }
}
After passing all tests with flying colors, I fired up the main application to do some actual environment testing.
To my surprise, due to a Nuget misconfiguration, my function caused an exception (System.IO.FileLoadException) after it was called, but before it entered the try-catch block and so it propagated back to the main application, causing havoc to code flow.
This got me thinking.
There are ways for exceptions to be thrown while calling the function but before a handler kicks in. There are also cases where an exception is simply unacceptable.
My current solution, was to create a wrapper function, which simply calls the actual function inside a try-catch. But this looks ugly and wrong. Plus I am not sure it is a bullet proof solution.
public static void TrackObject(object obj)
{
try { PrivateTrackObject(obj); }
catch { Console.WriteLine("Failed to track object."); }
}
private static void PrivateTrackObject(object obj)
{
Console.WriteLine(JsonConvert.SerializeObject(obj));
}
Is there a way to create a bullet-proof, no-way in hell, exception free method?
Or at least is there a definitive list of exceptions that can occur on a method call?
PS. The compiler warned me about the version mismatch, but I didn’t see it the first time.
PS2. I have created a sample project for anyone who wishes to see this issue in action.
https://drive.google.com/open?id=15BDrLNn87gsMHc9pQ-TgyDMSLQxDBq18
Is there a way to create a bullet-proof, no-way in hell, exception free method?
No. Even if the method is literally empty you can always have a thread abort exception thrown, or a stack overflow exception if there isn't enough space on the stack to call that method, or it could result in an out of memory exception.
is there a definitive list of exceptions that can occur on a method call?
If it's arbitrary code (i.e. from a delegate) then no. It could always be a custom exception of some type that didn't even exist when you wrote your code.
Also note that in your situation you need to be concerned about any possible exceptions that could be thrown in your catch block, if you just want to try handling normal exceptions (unlike the ones mentioned above) that happen in your try block. Just logging the exception could fail. In your example of using the console there could be problems with standard output that result in an exception. If you're really going for this code never throws you'd need to try to log the exceptions, but have other backup logging options for when they aren't working (and if you really can't throw, which as mentioned by others, is almost certainly a bad idea, then you need to be willing to go on without logging if logging your exceptions is failing).
Disclaimer: It is well known that catch (ex) { throw ex; } is bad practice. This question is not about that.
While digging through Microsoft reference sources, I noticed the following pattern in a lot of methods:
try {
...
} catch {
throw;
}
No logging, no debugging code—just a plain simple catch { throw; }.
Since, obviously, the guys at Microsoft should be fairly proficient in the use of C#, what could be the point of doing that instead of just omitting the catch block (and the try statement) altogether? Is there a technical reason for coding like this, or is it purely a stylistic choice?
Note: I don't know if it is relevant, but all such instances I could find also contain a try-finally block nested inside the try clause of the try-catch block.
It affects when exception filters run.
Given
void f() {
using (var x = AcquireResource()) {
x.DoSomething();
x.DoSomethingElse();
}
}
versus
void f() {
try {
using (var x = AcquireResource()) {
x.DoSomething();
x.DoSomethingElse();
}
} catch {
throw;
}
}
with
void g() {
try {
f();
} catch (Exception ex) when (h()) {
// ...
}
}
The first version of f would allow the filter h() to be called before x got disposed. The second version of f ensures that x is disposed before external code is run.
In the code you link to, SqlConnectionHolder is used a lot, and catch { throw; } blocks are all around the use of SqlConnectionHolder.
As C# Specification describes:
When an exception occurs, the system searches for the nearest catch clause that can handle the exception, as determined by the run-time type of the exception. First, the current method is searched for a lexically enclosing try statement, and the associated catch clauses of the try statement are considered in order. If that fails, the method that called the current method is searched for a lexically enclosing try statement that encloses the point of the call to the current method. This search continues until a catch clause is found that can handle the current exception, by naming an exception class that is of the same class, or a base class, of the run-time type of the exception being thrown. A catch clause that doesn't name an exception class can handle any 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.
in case of exception runtime first looks for catch clause that can handle it, which involve executing any associated exception filters. Undiscriminating catch block interrupt that search and make all nested finally blocks to be executed immediately.
That can be useful when you want to prevent caller from executing arbitrary code (in form of exception filter) before finally block. For example, when finally block affect security context of current thread.
Also, if exception will not be caught by any catch clause, then it will lead to thread termination. And in that case C# Specification did not provide any guaranty, that any finally block will be executed at all.
If the search for matching catch clauses reaches the code that initially started the thread, then execution of the thread is terminated. The impact of such termination is implementation-defined.
The code you linked is actually a very good example.
In my eyes, one should only use try catch blocks when dealing with things outside of their control, like file systems, external things basically.
In the code you linked the try catch is around the database stuff.
What this means is that by using this way of coding, they make sure there are no leaks, no connections remain open.
If anything goes wrong, such as wrong connection string, missing tables, whatever, the code is going to continue to execute, it will gracefully close the connection as shown in the finally block and it will finally throw meaning it will allow the client of that code to get the proper exception, get the entire stack as well and let them decide what to do when that happens.
To be honest I quite like what they did there.
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.
Can anyone please explain me use of throw in exception handling?
What happens when i throw an exception?
It means to "cause" an exception. When you "throw" an exception you are saying "something has gone wrong, here's some details".
You can then "catch" a "thrown" exception to allow your program to degrade gracefully instead of erroring and dying.
"Throwing" an exception is what triggers the entire process of exception handling.
In the course of normal execution, lines in a program are executed sequentially with loops and branches. When an error of some sort happens, an exception is created and then thrown.
A thrown exception will modify the usual order of operations in a program in such a way that no "normal" instructions will be executed until the exception is handled within a "catch" block somewhere. Once an exception is caught in a catch block, and the code within that catch block is executed ("Handling" the exception), normal program execution will resume immediately following the catch block.
// Do some stuff, an exception thrown here won't be caught.
try
{
// Do stuff
throw new InvalidOperationException("Some state was invalid.");
// Nothing here will be executed because the exception has been thrown
}
catch(InvalidOperationException ex) // Catch and handle the exception
{
// This code is responsible for dealing with the error condition
// that prompted the exception to be thrown. We choose to name
// the exception "ex" in this block.
}
// This code will continue to execute as usual because the exception
// has been handled.
When you throw an exception you're basically saying that some condition has happened beyond the reasonable means of the caller being expected to handle it. They're especially useful in constructors which have no way of signaling any form of construction failure (as they don't have return values).
When you throw an exception the runtime moves up the execution chain until it finds a catch block that is assignable to the type of exception you've thrown. On the way it runs the code in any finally blocks you may have, which allows you to (typically) release any resources you may have acquired.
The throw creates the exception to be handled. The object you passed then becomes the data that describes the exception.
Until something is thrown there is no exception to be handled.
Throwing an exception causes the exception to rise up the stack. There are two primary scenarios for a throw.
Have an exceptional condition unique to your code
if(inputVal < 0)
{
throw new LessThanZeroCustomException("You cannot enter a value less than zero");
}
The above code assumes you have coded an exception object called LessThanZeroCustomException. I would not actually name it this, but the Custom in the name is designed to illustrate you coded this. It would most likely inherit from
Have an exceptional condition that has been caught and needs to be rethrown. The normal reason for this is logging. In most cases, I dislike this pattern, as you end up spending time catching, logging and throwing over and over again. This is because most people doing this pattern try ... catch at every level. Yuck!
In short, throw means "I found an exceptional condition I cannot handle, so I am letting the person using this code know by throwing an exception".
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.