Handling Identical IO Exceptions In Different Code Blocks - c#

I'm working on a WinForms project that involves multiple IO calls. With IO comes great responsibility as many IO methods are fairly prone to exceptions (UnauthorizedAccess/file in use/etc.).
I'd like to know how to best handle the same exceptions throughout multiple spots in the code. For example, if I call FileInfo.CopyTo() in 7 different code blocks, all of which could throw UnauthorizedAccessExceptions, how should I handle that? I know that the general consensus dictates that exceptions should only be caught when they can be properly handled. I'm unsure of a "proper" way to handle an UnauthorizedAccessException, but I do want to display a MessageBox informing the user that the file was not copied.
In this case, I would have to wrap the 7 calls to CopyTo() in a try/catch statement and pop up the same MessageBox 7 times. To avoid reusing code, my first thought is to create something like this:
public void SafeCopy(FileInfo file, string targetPath)
{
try
{
file.CopyTo(targetPath);
}
catch (UnauthorizedAccessException ex)
{
MessageBox.Show(ex.Message);
}
}
This is obviously simplified and would handle additional exceptions. However, it doesn't quite feel right to create a "wrapper method" simply designed to handle exceptions for a single method call.
I know this could be considered subjective, but I feel there is a correct answer or alternate path here.

Related

Programmatic check or try...catch

I have some code here:
public static void OpenConnection(IDbConnection connection)
{
if(connection == null)
throw new ArgumentNullException("connection", "The connection was null.");
if (connection.State != ConnectionState.Closed)
connection.Close();
}
The code has to be executed quite a lot since I open and close the connection every time I do something in the database. I wonder if the next code would be a better solution performance wise:
public static void OpenConnection(IDbConnection connection)
{
try
{
connection.Close();
}
catch (NullReferenceException nullReferenceException) { throw; }
catch (Exception exception) { } // This will occur if the connection was already closed so nothing should be done then.
}
PS. Is the catch (Exception exception) { } necessary?
EDIT: Replaced ArgumentNullException by NullReferenceException in the second code since that will be the exception when the connection == null.
I wonder if the next code would be a better solution performance wise
Consider what the performance and functional difference is in each case:
connection is null
You will get a NullReferenceException instead of an ArgumentNullException, which is a functional difference since you get a different exception type (and less context on why/where the exception occurs). If you decide to catch the NullReferecenException and throw an ArgumentNullException, thne you have the overhead of throwing a new exception, so there's a performance hit.
The connection is not closed.
An attempt to close the connection is made - no real performance or functional difference here.
The connection is closed
You try to close the connection again. Probably not a huge functional difference here (since most providers probably don't get mad if you try to close a connection that's already closed), but it's unnecessary and may have some performance disadvantages depending on what the Close() method actually does.
So your second method has functional differences and may actually have a disadvantage performance wise.
Stick to the code that illustrates the expected behavior more cleanly - then only optimize if you have a measurable, correctable performance issue.
Apart from JDB's argument of exceptions being costly, take a close look at your code and tell me which of those is much easier to read/follow?
If you've never seen a method and it starts with a "try" you really need to think and take a close look. If it however starts with your guard clause (the if (connection == null) part), which by the way is a very common thing to do, you will see immediately without even having to think that if you pass null into the method you will get an exception. Take this guard clause as a contract. You never want null to be passed in there. It is much better design.
About the 'PS'. If you were to do this, remember that ALL other exceptions that might be thrown in connection.Close() will be caught and, unless done by you, never surface. Such things might get your application to incur bugs that are very hard to track down.
According to Microsoft, Exceptions are a huge performance hit. Try to avoid them whenever reasonable:
Throwing exceptions can be very expensive, so make sure that you don't throw a lot of them. Use Perfmon to see how many exceptions your application is throwing. It may surprise you to find that certain areas of your application throw more exceptions than you expected. For better granularity, you can also check the exception number programmatically by using Performance Counters.
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.
https://msdn.microsoft.com/en-us/library/ms973839.aspx#dotnetperftips_topic2
Your second example is actually a worse scenario. You should hardly ever catch general exceptions. You may think you know what will be thrown, but it's very possible that something unexpected will be thrown instead, leading to system instability and possible data loss/corruption.
It's Still Wrong to Use Catch (Exception e)
Even though the CLR exception system marks the worst exceptions as CSE, it's still not a good idea to write catch (Exception e) in your code. Exceptions represent a whole spectrum of unexpected situations. The CLR can detect the worst exceptions—SEH exceptions that indicate a possibly corrupt process state. But other unexpected conditions can still be harmful if they are ignored or dealt with generically.
In the absence of process corruption, the CLR offers some pretty strong guarantees about program correctness and memory safety. When executing a program written in safe Microsoft Intermediate Language (MSIL) code you can be certain that all the instructions in your program will execute correctly. But doing what the program instructions say to do is often different from doing what the programmer wants. A program that is completely correct according to the CLR can corrupt persisted state, such as program files written to a disk.
https://msdn.microsoft.com/en-us/magazine/dd419661.aspx
Your Second solution is not better for the performance, because your application will work harder when try block cause the exception, the catch block will try to catch exception. But the second solution is much better on logical point.
On your first solution you will get an error on your first check when connection is null.
Try-Catch or Try-Catch-Finally are powerful tools to handle errors, but they are expensive. Check out this link to see what you can do with it: Using Try... Catch..., Finally!
For better performance I would use:
private static void OpenSqlConnection(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
//Do some work
}
}
The above example creates a SqlConnection, opens it, does some work. The connection is automatically closed at the end of the using block.
For your code for Try-catch I would do (to catch exception):
try
{
conn.Close();
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.GetType().FullName);
Console.WriteLine(ex.Message);
//for Asp.net app
//Response.Write(ex.GetType().FullName);
// Response.Write(ex.Message);
}
For try catch please see: this link - Best Practices for Exceptions

Exception Handling on methods C#

Let's suppose I have the following code...
try
{
await Task.Run(() => autobuyandsell.Discard_Players(client, this));
if (stop == false)
{
await Task.Run(() => autobuyandsell.Buy_300_Players(client, this));
}
}
catch (ExpiredSessionException ex)
{
relogin = true;
b_stop.PerformClick();
}
Inside autobuyandsell the ExpiredSessionException can occur as I call some methods which can throw that Exception. My question is, do I need to add another try/catch block inside the function or it's enough to handle the extern Exception?
Answer accepted:
As the only need of my program is to exit the method and restart some variables, eventually, I decided to use try/catch outside the method.
You will catch them as you have it just now but you won't "know" if/how much of your Discard_Players or buy_300_Players code executed, and at which point the Exception occurred, etc. which may be a bad idea.
For example if these methods persist state to disk/database you wont "know" if this happened or not.
(I keep using the quotes on "know" because I guess it would be possible to interrogate the call stack etc when catching the Exception to find out where it was raised in order to find these things out but that's going to get messy pretty quickly!)
if you catch them INSIDE the methods you can control how they are handled (perhaps undoing any data you have persisted before throwing again so you can start afresh, for example) much better.
So depending on the functionality of these two functions YOU should decide which approach works best for YOUR application

Exception propagation in C#

Suppose I have three functions doA(), doB(), and doC() in a C# program where I know that doA() will call doB() which in turn calls doC().
Since doC() has to interact with a database, I know that it could very well generate exceptions that it won't be able to resolve that need to be brought to the user's attention. At the moment, I have the code which might throw the error in a try / catch blow in doC() and then the call to doC() in doB() in another try / catch and similarly the call to doB() in doA() in try / catch block. This allows me to just use throw; to kick the exception up to doA() where something can reasonably be done to display this to the user.
This seems a little like overkill though. I am wondering if since I don't plan on dealing with the exception in doB() or doC() if I can just get rid of the try / catch blocks there.
Assuming there are no finally blocks involved, what is the best practice for dealing with situations like this?
If your catch blocks are just like this:
catch (Exception)
{
throw;
}
then they are pointless indeed. You're not really handling the exception - don't bother with try/catch at all.
Personally I have very few try/catch blocks in my code - and although there are plenty of implicit try/finally blocks, most are due to using statements.
Yes I would get rid of the try/catch blocks - just let the exception propagate up to the top level and then catch it there. Catching an exception just to rethrow with throw; is simply not useful, although the following variation is actually harmful as it destroys the stack trace information:
catch (Exception exception)
{
throw exception;
}
You only need to catch if you intend to do something (or are trying to stop propagation). If you don't catch, it goes to the catch in the caller. In your case, it seems like doA() (or possibly its caller, depending on where you can handle it) is the only function that needs try/catch.
Exceptions bubble up the call stack.
If the method where the exception happens doesn't handle it, the methods caller gets it. If the caller doesn't handle it, it goes further up the call stack until the framework handles it and crashes your application.
To answer your question: there is no need to rethrow an exception in your case.
Type of exceptions you ll be catching can be different in every level, I m not sure what you are doing in 3 levels, but at the top of the stack you can only can 1 type of exception, in the lower level there might be different type of exception, which kinda forces u to use a broad exception type then a specific one, which might not have clear information in it.
So it depends on the types of Exceptions you ll be throwing.
IMHO, an exception should be caught the fewest number of times possible, it's actually a rather expensive operation to catch an exception.
The case might come up where you're crossing application layers, and might want one layer to log/rethrow, and the next layer up also needs to catch it. But in your case, it's just one layer so I'd say at the highest place in the call stack where you can do something with the exception, log it and do your business logic.
In short the answer to your question is yes. The only reason to catch an exception is to do something with it. If you can't do anything useful with it in DoC() then just let it bubble up.
It is always a good practice to have try catch blocks at the entry points to your code (typically in event handlers in a win forms app) so that nothing goes uncaught. At that point what you can do with it is tell the user.
However, you may also want to put some lower level handlers in place as appropriate if they can take reasonable action. For example, in doC() you might want to catch exceptions that have to do with deadlocks and retry. At some level you may also want to catch constraint errors and throw more meaningful user targeted errors in their place. I have a blog post about that here.

Eating Exceptions in c# om nom nom

Given that eating exceptions is always bad juju and re-throwing the exception loses the call stack, what's the proper way to re-factor the following?
Eating Exceptions:
try
{
… do something meaningful
}
catch(SomeException ex)
{
// eat exception
}
try
{
...
}
catch(SomeException e)
{
//Do whatever is needed with e
throw; //This rethrows and preserves call stack.
}
Catch and handle specific types of exceptions. Good practice is to not just catch System.Exception. A robust routine will strongly type the exceptions it knows how to handle.
Exceptions shouldn't be used for control flow, but there are often specific unwind procedures that need to be taken based on the type of exception.
Depending on the specific type, you may or may not choose to rethrow it. For example, an ASP parsing exception being thrown to an error page that USES the code causing the exception will cause an infinite loop.
try
{
}
catch( FileIOException )
{
// unwind and re-throw as determined by the specific exception type
}
catch( UnauthorizedAccessException )
{
// unwind and re-throw as determined by the specific exception type
}
catch( SomeOtherException )
{
// unwind and re-throw as determined by the specific exception type
}
catch( Exception )
{
// log and re-throw...add your own message, capture the call stack, etc.
// throw original exception
throw;
// OR, throw your own custom exception that provides more specific detail and captures
// the original exception as the inner exception
throw new MyStronglyTypedException();
}
finally
{
// always clean up
}
Most people think it's utterly evil to eat/suppress exceptions, especially with catch-alls. (Ironically, they use the catch all response of "don't use catch-alls, it's evil" :-). I don't understand the religious fervour with which people parrot this view, because if used sensibly, there is nothing wrong with this approach.
In my book, the worst case scenario is that my program catastrophically exits -> this creates a very unhappy customer with a total data loss situation. An unhandled exception is guaranteed to cause this every time. So failing to handle an exception is statistically more dangerous than any risk of instability that may occur if an exception is suppressed. In light of this, anything we can reasonably do to protect against an unhandled exception occurring is a good thing.
Many people seem to forget that catch alls can often handle any exception correctly, even if they don't know the details of what the exception was. By this I mean that they can guarantee that the program state remains stable, and the program continues to run within its design parameters. Or there may even be side effects such as the user finding a button unresponsive, but they still won't lose any data (i.e. graceful degradation is better than a fatal crash). For example, sometimes you want to return one value on success and a default if you fail for any reason. Part of designing code is knowing when to report errors to the user and when to fix a problem on their behalf so their program "just works". In this situation, a well designed catch-all is often the correct tool for the job.
Exceptions worry me. Fundamentally an exception is a guaranteed program crash if I don't handle it. If I only add specific exception handling for the exceptions I expect, my program is inherently fragile. Consider how easily it can be broken:
If a programmer forgets to document one exception they might throw, I won't know I need to catch it, and my code will have a vulnerability I'm not aware of.
If someone updates a method so that it throws a new exception type, that new exception could ripple up the call stack until it hits my code. But my code was not built to handle the exception. Don't tell me that the libraries I'm calling will never change.
Every exception type you specifically handle is another code path to be tested. It significantly multiplies the complexity of testing and/or the risks that a broken bit of handling code might go unnoticed.
The view underpinning the "suppression is evil" view is that all exceptions represent an instability or error - but in many cases programmers use exceptions to return little more than status information. For example, FileNotFound. The programmer writing file I/O code has decided on my behalf that a missing file is a fatal error. And it might be. It is up to me to catch this and decide that actually it's a common and perfectly normal, or expected, situation. A lot of the time, suppressing exceptions is necessary to simply stop someone else's "decision" taking out my application. The old approach of simply ignoring error return codes wasn't always a bad thing, especially given the amount of effort it takes to catch and suppress the myriad "status" exceptions that are bandied about.
The trick to silently eating/suppressing exceptions is just to be sure that this is the correct way to handle them. (And in many cases, it's not). So there may be no need to refactor your example code - it might not be bad juju.
That all depends on where the code lives.
In the depths of the system? If that is the case then I would gather some form of standard error handling should exist across the product, if not it needs to.
If it is on the presentation side for instance it may have no value to anyone except the code, and in that case additional logic may need to be placed in a finally block.
Or let it roll up hill altogether and don't wrap it in a try catch if you aren't going to do anything useful in the catch anyways.
… do something meaningful
To add to the excellent comments already provided.
There are three way to "re-throw" an exception:
catch (Exception ex)
{
throw;
}
The above preserves the call stack of the original exception.
catch (Exception ex)
{
throw ex;
}
The above eats the original exception chain and begins a new one.
catch (Exception ex)
{
throw new MyException("blah", ex);
}
The above adds the original exception to the InnerException of a new chain. This can be the best of both worlds, but which one is correct is highly dependent on what you need.
Your code can be rewritten (to eat exception) like this
try
{
… do something meaningful
}
catch
{
// eat exception
}
But I don't understand what you want to do by refactoring!!
Edit:
Re-throwing using throw; doesn't work always. Read this ->
http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx
In general, it's not a good idea to catch the general Exception unless you can actually handle it. I think the right answer is a combination of Tim's and Joshua's answers. If there are specific exceptions that you can handle and remain in a good state, for example FileNotFoundException you should catch it, handle it, and move on, as seen here:
try
{
// do something meaningful
}
catch(FileNotFoundException)
{
MessageBox.Show("The file does not exist.");
}
If you can't handle it and remain in a good state, don't catch it in the first place.
However, one case where you would want to catch the general Exception and re-throw it would be if you have any cleanup that you will need to do, for example aborting a database transaction, before the exception bubbles up. We can accomplish this by extending the previous example like so:
try
{
BeginTransaction();
// do something meaningful
CommitTransaction();
}
catch(FileNotFoundException)
{
MessageBox.Show("The file does not exist.");
AbortTransaction();
}
catch(Exception)
{
AbortTransaction();
throw; // using "throw;" instead of "throw ex;" preserves
// the stack trace
}
Refactor it to:
// No try
{
… do something meaningful
}
// No catch
and let the exception be handled at the main loop.
if the catch() block only rethrows exception and does not do any real exception handling then you don't need try..catch at all.
Part of the problem with eating exceptions is that it's inherently unclear what they're hiding. So... the question of the proper refactoring isn't easily answered. Ideally, however, you'd remove the try...catch clause entirely; it's unnecessary in most cases.
Best practice is to avoid try...catch entirely wherever possible; if you must deal with exceptions, then do so as locally and specifically as possible and don't propagate them up the stack; finally, include a global unhandled exception handler that does the appropriate logging (and perhaps offers to restart the application if necessary).
Unless the catch block actually does something with the exception (e.g., logging it to a system error file), there is no need to even have the try/catch block.
That being said, if the exception is worth informing the user about (e.g, logging it), then by all means use a catch block to do so.
One particularly bad pitfall of ignoring exceptions is that certain (fatal) exceptions should cause the program to terminate. Such exceptions (e.g., failure to load a class) leave the program in an unstable state, which will only lead to disaster later on in the execution. In these cases, logging the exception and then gracefully terminating is the only reasonable thing to do.
The particular way in which exceptions are eaten is not important. Never eat exceptions by any means!
Only catch exceptions that are expected to occur and which you can do something about. Examples of this include file and network IO, security exceptions, etc. For those cases you can display an explaination of what happened to the user, and sometimes you can recover gracefully.
Do not catch exceptions that should never occur. Examples of these are null-reference exceptions, invalid operation exceptions, etc. The code should be written so that these exceptions will never happen, so there is no need to catch them. If those exceptions are happending, then fix the bugs. Don't swallow the exceptions.
It is OK to log all exceptions, but this should be done with the unhandled exception handler on the program and any threads that are created. This is not done with a try/catch.
You can rethrow exception without losing call stack just re-throw as
catch(Exception e)
{
throw;
}
Why would you need this?
Usage example:
Somewhere in your app you have 3rd party code and you wrap it, and if it throws exceptions you throw WrappingException.
When you execute some other code you might get exception either from 3rdparty or either from your own so you may need:
try
{
//code that runs 3rd party
//your code, but it may throw Null ref or any other exception
}
catch( WrappingException)
{
throw;
}
catch( Exception e)
{
throw new MyAppLayer3Exception("there was exception...", e);
}
In this case you do not wrap WrappingException with your MyAppLayer3Exception.
So, at the top level of you application you may catch all exceptions and by knowing Type of exception you will know where from it came!
Hope it helps.
eating exceptions is not always "bad juju". There is no magic here; just write code to do what you need to do. As a matter of hygiene, if you catch an exception and ignore it, comment as to why you are doing it.
try
{
.....
}
catch (something)
{
// we can safely ignore ex becuase ....
}
Sometimes, it's just best not to deal with exceptions if you really don't want to deal with the added responsibility that comes with exceptions. For example, rather than catching an NullReferenceException, why not just make sure that the object exists before you try to do something with it?
if (yourObject != null)
{
... do something meaningful with yourObject ...
}
Exceptions are best reserved to handle those things you really have no control over, such as the sudden loss of a connection, or things which have the potential to kill a long-running process, such as a data import. When an exception is thrown, regardless of the reason, your application has reached a point of instability. You catch the exception to return the application to a point of stability by cleaning up the mess, e.g. disposing of the lost connection and creating a new one OR logging the line where the error occurred and advancing to the next line.
I've been dealing with exception handling for the last 15 years, starting with the first six versions of Delphi, up to (and including) .NET 1.0-4.0. It is a powerful tool, but it is a tool that is often overused. I have found consistently, during that time, the most effective exception handling process is deferring to if-then before try-catch.
One major problem with the exception hierarchy is that exceptions are categorized based upon what happened, rather than based upon the system state. Some exceptions mean "a function couldn't perform its task, but it didn't disturb the system state either". Others mean "Run for your lives! The whole system is melting down!" In many cases, it would be entirely proper for a routine which could handle the failure of a called method to swallow any and all exceptions of the former type; in other cases, such exceptions should be rethrown in a manner which indicates possible state corruption (e.g. because there was a failure in an operation necessary to reset the system state; even though the attempt to perform that operation didn't disturb anything, the fact that the state wasn't reset means it's corrupted).
It would be possible for one to manage one's own exceptions into such a hierarchy, but I don't know any good way to deal with other exceptions.

Exception catching best practice (c#/.net)

If I have code like this:
void a()
{
try
{
b();
}
catch (MyException)
{
// Handle any problems that occurred in b(c(d()))
}
}
void b()
{
c();
// Do something else
}
void c()
{
d();
// Do something else
}
void d()
{
// Do something, throw a MyException if it fails
}
Assuming no cleanup is necessary at any point, is it best to put a try{}catch{throw;} around the call to d() in c() and the call to c() in b() or is it considered OK to let the exception from d() bubble up to a() "naturally" without any intervening try/catch blocks?
I suppose the extra try/catch block act as a sort of "documentation" but they seem superfluous so I'm just wondering what other people would consider the best way.
Sorry if this is all a bit too basic, I'm trying to get my head around exceptions but I don't seem to have a good feel for them yet.
Let it propagate until you can handle it. If you can't handle it, there's no point catching it. So the question is, can you effectively handle the exception inside the c() method?
Basically, no. This is not the suggested way to handle these situations.
You should catch exceptions if and only if you can either handle them and do something appropriate with them or to provide more info to the callers higher in the call stack (by encapsulating it in a more generic exception). If you can't do it, you should let the exception bubble up in the call stack until someone can handle it appropriately.
The great advantage of exceptions is that you can deal with problems where you can do womething about them, rather than directly in the function where e.g. a missing file is detected, or in the function's caller, or its caller, &c.
However, exceptions also have to be handled somewhere along the chain. Where these points occur depend on the framework you are using, and what its exception management consists of. The key question is: what are your points of entry where allowing an exception to escape uncaught would have bad effects? Typical examples include
Event processing code in interactive UI applications (which at least in WinForms and ASP.NET can be caught en masse by providing exception event handlers).
Integration points where you respond to external messages (e.g. picking up messages from a queue, processing a file, listening on a named pipe, implementing a WCF service).
Timer events where you do background processing.
Thread start methods.
Sometimes, you also want to catch a low-level general technical error and rethrow it as a more domain-specific exception. This typically done in well-designed libraries to shield users from its internal implementation details. In an enterprise application, you might want to catch certain SqlExceptions and rethrow them as application-specific exceptions (e.g. YourApp.UnknownCustomer), in order to deal with them at higher levels of logic.
My advice would be: deal with problems at the highest level possible, but ensure that the exception catchers up there have reasonable exceptions to work with. And, by the way, unless you hate your users, don't display the exception and its stack trace to them! ;-)
I'd say, it depends on what you want to do with the information.
I always try to catch problems as close to the source as possible - why run all the way back with the problem, instead of trying to deal with it where it happens? For readability and understanding of the code, I also believe in try/catch as close to the source of the problem as possible.
If you're writing the program for yourself, and noone else will ever touch it, do whatever works best for you and the code.

Categories

Resources