Exception Handling on methods C# - 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

Related

no need to use finally in try catch block if catching all exceptions? [duplicate]

This question already has answers here:
Is finally block in C# a must?
(7 answers)
Closed 1 year ago.
If I catch all exceptions;
try
{
... //code causes error
}
catch (Exception e)
{
...//handle all exceptions
}
So there is no need to use Finally block? since I catch all exceptions, the program will continue to execute the code after try-catch?
Another questions is, if use a finally block, how can I catch the errors happened in the final block itself? I mean it looks like we only need to put everything in the try and catch block which is in the very end?
So there is no need to use Finally block?
The finally clause has very little to do with what, how and how many exceptions you catch. Think of the code that goes in a finally clause as clean up code that must be run independently of what happens inside the try clause. A typical scenario is the following (I'll use some C#7 for the fun of it):
(bool Succesful, object Result) TryDoSomethingDangerous()
{
var someDisposableObject = new SomeDisposableObject();
try
{
var result = someDisposableObject.DoSomethingDangerous(); //documented to be able to throw SomethingBadHappenedException
return (true, result);
}
catch (SomethingBadHappenedException e)
{
Logger.Log(e);
InformUserSomethingWentWrong(e);
return (false, null);
}
finally
{
someDisposableObject.Dispose();
}
}
since I catch all exceptions, the program will continue to execute the code after try-catch?
This is worrying. Yes if you catch all exceptions your code will keep running (how long is anyone's guess), but this is, in general, a very bad idea. You should only deal with exceptions you know how to fix and recover from. Swallowing exceptions just to keep trudging along is bound to end in disaster.
In general, catch (System.Exception) is a bad idea unless you are planning to simply log information and re throw immediately.
Another questions is, if use a finally block, how can I catch the errors happened in the final block itself? I mean it looks like we only need to put everything in the try and catch block which is in the very end?
Again, you are completely misunderstanding the execution flow in try-catch-finally. Code in finally is code that must run no matter what happens inside the try clause. You seem to believe that it's code that should only run if there is an exception.
In general, its better if code inside a finally clause is robust and does not throw exceptions itself. If, given the circumstances, this is not possible then the code inside the finally clause will need to have its own exception handling mechanism. In my case I try to avoid this kind of scenario and refactor code accordingly.
In situations such as releasing resources, it is used twice instead of writing the same code (both try and catch). Such as closing the database connection and disposing of an object

Why compiler does not allow using await inside catch block

Let say I have an async method:
public async Task Do()
{
await Task.Delay(1000);
}
Another method is trying to call Do method inside catch block
public async Task DoMore()
{
try
{
}
catch (Exception)
{
await Do(); //compiled error.
}
}
But this way, the compiler does not allow using await inside catch, is there any reason behind the scene why we could not use it that way?
Update
This will be supported in C# 6. It turned out that it wasn't fundamentally impossible, and the team worked out how to do so without going mad in the implementation :)
Original answer
I strongly suspect it's the same reasoning that prevents yield return from being used in a catch block.
In particular:
First off, we still have the problem that it is illegal to "goto" into the middle of the handler of a try-protected region. The only way to enter a catch block is via the "non-local goto" that is catching an exception. So once you yielded out of the catch block, the next time MoveNext was called, we’d have no way to get back into the catch block where we left off.
Second, the exception that was thrown and caught is an intrinsic part of the execution of the catch block because it can be re-thrown using the "empty throw" syntax. We have no way of preserving that state across calls to MoveNext.
Replace "yield" with "await" there, and I think you'll have your answer.
It feels like it would be an odd thing to want to do in most cases, and you should usually be able to rewrite your code fairly easily to await after the catch block - unless you were trying to await something and then throw, of course. In that case it would be a bit of a pain, I admit...

C# Re-throwing Exceptions

When throwing exceptions between multiple methods, should all methods re-throw the exception? for example
Method1()
{
Method2();
}
Method2()
{
try
{
// Do something
}
catch
{
throw;
}
}
try
{
Method1();
}
catch
{
// Do something about exception that was thrown from Method2()
}
Notice how in Method1(), I didn't need to wrap Method2() in a try block, should I be?
You don't need to wrap everything in try blocks.
You should only try when you want to catch something, and you should only catch something in the following cases:
You're ready to handle the exception (do whatever needs to be done and don't let it propagate up the stack),
You want to do something with the exception (e.g. log it) before rethrowing it (by using the parameterless form of throw),
You want to add details to the exception by wrapping it in another exception of your own (see Allon Guralnek's excellent comment below).
You do not need to try, catch, and rethrow exceptions unless you have some particular reason for catching them in the first place. Otherwise, they'll automatically get bubbled up from the lower level functions that throw them to the highest level function in your code. Essentially, you can think of them as getting "rethrown" all the way up, even though this isn't technically what is happening.
In fact, most of the time that you see a try/catch block written, it's incorrect. You should not catch exceptions unless you can actually handle them. It's utterly pointless (and in fact considered to be bad practice) to catch exceptions just to rethrow them. Do not wrap all of your code within try blocks.
Note that by "handle them", I mean that your code in the catch block will take some specific action based on the particular exception that was thrown that attempts to correct the exceptional condition.
For example, for a FileNotFoundException, you might inform the user that the file could not be found and ask them to choose another one.
See my answer here for more detail and a thorough discussion of "exception handling best practices".

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.

Categories

Resources