There are multiple questions (1,2,3,4 etc. etc.) called "Why isn't this exception caught". Sadly, none of these solutions work for me... So I am stuck with a truly uncatchable exception.
I have a piece of code (.NET 4.0) that checks a large textfile for digits and numbers. Whilst testing I got a runtime exception:
What you see here is a try-catch pattern with a catchblock for an ArgumentOutOfRangeException. But during runtime, the try block throws an ArgumentOutOfRangeException that is not being caught.
I read the C# language specification section about the try-catch structure, and it says:
A catch block of a try statement is reachable if the try statement is reachable.
So in theory the above code should catch the exception.
Then I thought it might had something to do with the fact that this code is running in a task (during the processing of the textfile I also want to update the UI so I do it asynchronous). I searched around and then I found this answer by Jon Skeet. Basically suggesting I use Task.Wait in a try-catch block to catch any exceptions.
The problem I am facing now is that I can't really call Task.Wait because that would block the calling thread which is my UI thread! Then I figured that I could create an extra tasklayer to wait for that task:
//Code called from the UI
System.Threading.Tasks.Task.Factory.StartNew(()=>
{
//Create a new task and use this task to catch any exceptions
System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(MethodWithException);
try
{
task.Wait();
}
catch(Exception)
{
MessageBox.Show("Caught it!");
}
});
But this still gives the same result... Then I thought that it could be because of the fact I am not specific enough with my Exceptiontype. But the C# Language Specification states:
Some programming languages may support exceptions that are not representable as an object derived from System.Exception, although such exceptions could never be generated by C# code.
So unless you use some sketchy third party API you're always good when you use Exception. So I found myself with an suggested answer by Jon Skeet that didn't quite work for me. That's when I knew I should just stop trying...
So does anyone know what is going on? And how can I fix this? I know I could just check if i is equal or bigger than text.Length but understanding what's happening is more important than working code.
This is simply an artifact of the debugger.
In the Debug menu, there's an option called Exceptions... Click it, and make sure to uncheck the "Thrown" checkbox here:
Many times, you'll want to see the error in context, even if it's inside a try/catch, which is what this setting is for. In this case, that is exactly what you ought to be doing, so that you can see compare i to the length of text and see where your problem is.
If you ran the code without the debugger (such as by double-clicking the executable or using the "Start without Debugging" option), you would "correctly" throw away the error without any alerts.
I just wrote the following test:
[TestMethod]
public void ArgumentOutOfRangeExceptionTest()
{
string test = "abc";
int i = 0;
try
{
while (true)
{
test.ElementAt(i);
i++;
}
}
catch (ArgumentOutOfRangeException)
{ }
}
It is working fine. I believe that you had another exception, which is not called in your calling code.
There is only one exception I know which can't be caught. It's the StackOverflowException. See this question about it.
Related
I have a whole sequence of interlinked questions. I would like to know answers for all of them independantly, so *yes*, some of them appear to be X-Y questions; but I do want to know the solution to them anyway!. See end of question for list of other questions in this set.
I have a situation in which calling Marshal.GetExceptionForHR(code, pointers) throws an AccessViolationException.
Apparently this a VeryBadThing. So bad that try...catch just shrugs at me and wanders off for a fag ... which I didn't know was a thing :(
Suppose a premise of "calling .GetExceptionForHR() is what I want to do" (see other questions for a discussion of whether this is a good idea!).
Suppose further that whatever causes the AccessViolation is unavoidable in some scenarios.
Given those premises, is there any way to predict in advance that calling them method will blow up?
Some equivalent of TryGetExceptionForHR() that'll return false rather than blowing up my entire Program.
Other questions in this problem set.
C#: How do I prevent a pipe reading error, when closing the exe on one end of a DuplexChannel connected by Named Pipes?
Ascertain reason for Channel Fault in WCF+NamedPipes
Is using the `Marshal` static class in otherwise normal C# code unwise?
Is there a way to predict that `Marshal.GetExceptionForHR(code, pointers)` would throw an `AccessViolationException`
Is this a suitable use of `HandleProcessCorruptedStateExceptions`
Just having a look at the Microsoft docs, Marshall.GetExceptionForHR doesn't throw an exception that can be caught.
Instead, they recommend using Marshall.ThrowExceptionForHR to get a thrown exception that you can then handle. This does not throw an exception when using a success HResult.
If you want to use Marshall.GetExceptionForHR then double-check that the correct pointer is being used. IntPtr(0) will use the current IErrorInfo interface while IntPtr(-1) will attempt to reconstruct the exception from just the code.
It's also possible that rather than throwing unexpected exceptions, GetExceptionForHR just returns the unexpected exception from a catch block e.g.:
catch(Exception ex)
{
return ex;
};
Unfortunately, I can't be 100% certain at this point, I'm trying to track down the Marshall class on Microsoft's Github and I'll run some of my own attempts to see if I can get the same effect as yourself.
Related links:
ThrowExceptionForHR
GetExceptionForHR
I sometimes run into situations where I need to catch an exception if it's ever thrown but never do anything with it. In other words, an exception could occur but it doesn't matter if it does.
I recently read this article about a similar thing: http://c2.com/cgi/wiki?EmptyCatchClause
This person talks about how the comment of
// should never occur
is a code smell and should never appear in code. They then go onto explain how the comment
// don't care if it happens
is entirely different and I run into situations like this myself. For example, when sending email I do something similar to this:
var addressCollection = new MailAddressCollection();
foreach (string address in addresses)
{
try
{
addressCollection.Add(address);
}
catch (Exception)
{
// Do nothing - if an invalid email occurs continue and try to add the rest
}
}
Now, you may think that doing this is a bad idea since you would want to return to the user and explain that one or more messages could not be sent to the recipient. But what if it's just a CC address? That's less important and you may still want to send the message anyway even if one of those addresses was invalid (possibly just a typo).
So am I right to use an empty catch block or is there a better alternative that I'm not aware of?
You are completely right to use an empty catch block if you really want to do nothing when a certain type of exception occurs. You could improve your example by catching only the types of exceptions which you expect to occur, and which you know are safe to ignore. By catching Exception, you could hide bugs and make it harder for yourself to debug your program.
One thing to bear in mind regarding exception handling: there is a big difference between exceptions which are used to signal an error condition external to your program, which is expected to happen at least sometimes, and exceptions which indicate a programming error. An example of the 1st would be an exception indicating that an e-mail couldn't be delivered because the connection timed out, or a file couldn't be saved because there was no disk space. An example of the 2nd would be an exception indicating that you tried to pass the wrong type of argument to a method, or that you tried to access an array element out of bounds.
For the 2nd (programming error), it would be a big mistake to just "swallow" the exception. The best thing to do is usually to log a stack trace, and then pop up an error message telling the user that an internal error has happened, and that they should send their logs back to the developers (i.e. you). Or while developing, you might just make it print a stack trace to the console and crash the program.
For the 1st (external problem), there is no rule about what the "right" thing is to do. It all depends on the details of the application. If you want to ignore a certain condition and continue, then do so.
IN GENERAL:
It's good that you are reading technical books and articles. You can learn a lot from doing so. But please remember, as you read, you will find lots of advice from people saying that doing such-and-such a thing is always wrong or always right. Often these opinions border on religion. NEVER believe that doing things a certain way is absolutely "right" because a book or article (or an answer on SO... <cough>) told you so. There are exceptions to every rule, and the people writing those articles don't know the details of your application. You do. Make sure that what you are reading makes sense, and if it doesn't, trust yourself.
An empty catch block is fine in the right place - though from your sample I would say you should cetagorically NOT be using catch (Exception). You should instead catch the explicit exception that you expect to occur.
The reason for this is that, if you swallow everything, you will swallow critical defects that you weren't expecting, too. There's a world of difference between "I can't send to this email address" and "your computer is out of disk space." You don't want to keep trying to send the next 10000 emails if you're out of disk space!
The difference between "should not happen" and "don't care if it happens" is that, if it "should not happen" then, when it does happen, you don't want to swallow it silently! If it's a condition you never expected to occur, you would typically want your application to crash (or at least terminate cleanly and log profusely what's happened) so that you can identify this impossible condition.
If an exception should never be thrown then there is no point catching it - it should never happens and if it does you need to know about it.
If there are specific scenarios that can cause a failure that you are OK with then you should catch and test for those specific scenarios and rethrow in all other cases, for example
foreach (string address in addresses)
{
try
{
addressCollection.Add(address);
}
catch (EmailNotSentException ex)
{
if (IsCausedByMissingCcAddress(ex))
{
// Handle this case here e.g. display a warning or just nothing
}
else
{
throw;
}
}
}
Note that the above code catches specific (if fictional) exceptions rather than catching Exception. I can think of very few cases where it is legitimate to catch Exception as opposed to catching some specific exception type that you are expecting to be thrown.
Many of the other answers give good reasons when it would be ok to catch the exception, however many classes support ways of not throwing the Exception at all.
Often these methods will have the prefix Try in front of them. Instead of throwing a exception the function returns a Boolean indicating if the task succeeded.
A good example of this is Parse vs TryParse
string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
//This code is only executed if "s" was parsed succesfully.
aCollectionOfInts.Add(i);
}
If you try the above function in a loop and compare it with its Parse + Catch equilvilant the TryParse method will be much faster.
Using an empty catch block just swallows the Exception, I would always handle it, even if it is reporting back to you that an Exception occurred.
Also catching the generic Exception is bad practice due to the fact it can hide bugs in your application. For example, you may have caught an ArgumentOutOfRange exception which you did not realize was happening and then swallowed it (I.e. not done anything with it).
Sometimes i meet the following construction exploring ServiceStack's code base:
try
{
...
}
catch (Exception)
{
throw;
}
In my oppinion this construction does nothing. What is the possible reason of doing this?
You're right - it's generally pointless. I have seen people include it so that they can put a break point on the throw line (so they get to see when an exception is thrown, even if they're not breaking on exceptions in general). Unfortunately it often gets left in there after the debugging session has finished.
If you encounter this within a code base you control, I suggest you remove it.
Last time I stumbled over such a construct I asked the author why. Why I was particulary curious was that he did not do this all willy nilly but only in a few places.
His response came with the 'let exceptions be exceptional' which I guess he must have picked up from Eric Lippert where he added that most of his methods would/(should) never throw where in some places his code could throw. By adding the try/catch/throw he was communicating to maintainers that he had recognized that this could happen.
Naturally we try to write code that does not blow up at all. For example by using Code Contracts the number of methods that actually can throw is reduced dramatically.
I'm looking for the best method of handling errors in a c# winforms class that I have. The gist of the application is that it has a data analyzer that analyzes the data for statistics and other such stuff. However, I'm looking for the proper way of handling an ABORT.
For example, I have the class called Analyzer
namespace PHOEBE
{
public class Analyzer
{
public Analyzer(){
DoAnalysis();
DoFurtherAnalysis();
}
public class DoAnalysis(){
try{
Convert.ToInt32("someNumber...."); //obviously fails..
}
catch{
//ERROR OCCURRED, ABORT ALL ANALYSIS
return;
}
}
}
Obviously, when DoAnalysis() is called, there will be an error that occurs. The catch block will catch the exception. However, when this catch occurs, it will return to the constructor and run DoFurtherAnalysis(). This is a problem.
I know that you could do return values from each method where each value indicates a certain outcome (ie. 1 = success, 0 = fail). However, a lot of the methods I call, use return values already. I could also use a boolean that gets flagged when an error occurs and check that value before calling the next method from the constructor, but checking this value each time is annoying and repetitive.
I was really hoping for some sort of like "abort mechanism" that I could use. Is there any other ways of working around this? Any interesting work-arounds for this?
Assume this class is being called from a form.
Just let the exception propagate up - you should only catch the exception if you can actually handle it. Exceptions are the "abort mechanism" in .NET. You're currently swallowing the signal that everything's gone wrong, and returning as if all were well.
Generally I find catching exceptions to be pretty rare - usually it's either at the top level (to stop a whole server from going down just because of one request) or in order to transform an exception of one kind into another in order to maintain appropriate abstractions.
I was really hoping for some sort of like "abort mechanism" that I
could use. Is there any other ways of working around this? Any
interesting work-arounds for this?
Yes, there is. It is called exception handling.
Let's rewrite your code:
namespace PHOEBE
{
public class Analyzer
{
public Analyzer()
{
try
{
DoAnalysis();
DoFurtherAnalysis();
}
catch
{
//ERROR OCCURRED, ABORT ALL ANALYSIS
return;
}
}
public class DoAnalysis()
{
Convert.ToInt32("someNumber...."); //obviously fails..
}
}
Now, the constructor will abort and not run the second method since the exception will "bubble through" and be catched where you want it.
On an unrelated note: Please try to catch as specific exceptions as possible, in this case a FormatException
You are subverting the existing "abort" mechanism by catching an exception that you are not doing anything about and swallowing it.
You should not use a try{}catch{} block in this case and let the exception bubble up and cause the application to abort.
The easiest work-around is don't catch the exception. If that were to happen, it'd go straight past the DoFurtherAnalysis() function and out to the original caller.
Don't see anything anoying in returning and checking bool return value from the function. It's much much better solution then having some tricky internal state management, that you for sure will messed up after a couple of months when you return to your code.
Make code sumple and streghtforward. It's not anoying, it's good.
In your specific case if you want just abort everything, just do not catch exception it will abort your program.
use a try...catch in the constructor?
Well, you've got several issues mixed up here. First, it looks like you do possibly-very expensive processing from your constructor. If that processing can throw, you really don't want to call it from your constructor becuase you don't even have the option of returning an error code.
Second, (and you'll read in many threads here,) how you handlee errors really depends on the application and expectation of your users. Some errors could be corrected by changes to inputs. Others might happen in the middle of the night if analysis takes a long time and you might want to continue with another analysis, logging this error.
So I think we're really going to punt back to you for more information about the above.
You could just move DoFurtherAnalysis(); into the the try block
And I would do this entire process somewhere other than the constructor.
Only thing I ever do in the constructor is initialize properties.
I'll try and ask my question so it doesn't end as a simple argumentative thread.
I've jumped into an application coded in C# recently and I'm discovering the exception mechanism. And I've had a few bad experiences with them such as the following
// _sValue is a string
try
{
return float.Parse(_sValue);
}
catch
{
return 0;
}
I changed it into :
float l_fParsedValue = 0.0f;
if (float.TryParse(_sValue, out l_fParsedValue))
{
return l_fParsedValue;
}
else
{
return 0;
}
Result, my Output in Visual Studio is not anymore flooded with message like
First chance System.FormatException blabla
when string like '-' arrive in the snippet. I think it's cleaner to use the second snippet.
Going a step further, I've often seen that exceptions are too often used ilke: "I do whatever I want in this try-catch, if anything goes wrong, catch.".
Now in order to not get stuck with bad misconceptions, I would like you guys to help me clearly define how/when to use those exceptions and when to stick with old school "if...else".
Thanks in advance for your help!
You should throw exception in exceptional cases. i.e. when something unexpected happens. If you expect a function to regularly throw an exception that's most likely bad design.
In your examples it is very clear that TryParse is better since the exception seems to occor often.
But for example when parsing a file, I expect it to be almost always valid. So I usually use Parse and catch the exception and generate a InvalidDataException with the caught exception as inner exception. Usually simplifies the parsing code a lot, even if it may be bad style.
I recommend Eric Lippers's blog entry: Vexing exceptions
In case of Parse()/TryParse() it's better don't wait for exception, use TryParse and act on incorrect input by yourself.
Exceptions should be used for exceptional behavior, not for flow-control. A basic guideline would be that if normal program flow regularly runs into exceptions you're doing something wrong.
However, it is important to notice that just having a try { } catch { } present will itself not affect performance negatively. Only when an exception is actually thrown and the stack trace needs to be computed you will see (in some cases quite severe) performance degradation.
Another point that hasn't been examined in depth so far is that Exceptions have a cost. They subvert the normal flow of control in the program and there is some resource use as a result.
A simple test would be to write a program that loops over your original float.Parse code with some invalid data, and compare how long it takes to run versus the TryParse version - there will be a small but noticeable difference.
A snippet that sticks in my mind when making decisions about exceptions is from this article:
Almost Rule #1
When deciding if you should throw an
exception, pretend that the throw
statement makes the computer beep 3
times, and sleep for 2 seconds. If
you still want to throw under those
circumstances, go for it.
Programs that use exceptions as part
of their normal processing suffer from
all the readability and
maintainability problems of classic
spaghetti code.
— Andy Hunt and Dave Thomas
I think there is no simple right answer about how/when to use exceptions. It depends on an architecture of the application you're working on and other factors.
I can suggest you to read the chapters 8.3. Error-Handling Techniques and 8.4. Exceptions of the Code Complete book.
Ahh, if only it was that simple! But, alas - the decision when to use exceptions is more often subjective than not. Still, there are guidelines you can use. For example, Microsoft has some.
All in all, the rule of thumb for throwing exceptions is - you only throw an exception when a function cannot do what it was supposed to do. Basically each function has a contract - it has a legal range of input values and a legal range of output values. When the input values are invalid, or it cannot provide the expected output values, you should throw an exception.
Note that there is a slippery point here - should validation (of user input) errors also be thrown as exceptions? Some schools of thought say no (Microsoft included), some say yes. Your call. Each approach has its benefits and drawbacks, and it's up to you to decide how you will structure your code.
A rule of thumb for catching exceptions is - you should only catch exceptions that you can handle. Now, this is also slippery. Is displaying the error message to the user also "handling" it? But what if it's the infamous StackOverflowException or OutOfMemoryException? You can hardly display anything then. And those might not be the only exceptions that can leave the whole system in an unusable state. So again - your call.