views:

97

answers:

4

Hi

I have application reads in data from text file. Recently I realized that I should make a data checker for the data in the text file, to see if I can display/handle it correctly.

Basically at the moment all the checker does is see if data is in the correct format, i.e. double is a double, int is int, etc... And if it isn't I'm throwing an exception.

Like so:

private static string CheckDouble(string doublevar)
        {
            double tryParseDoubleResult;
            var tryParseDouble = double.TryParse(doublevar, out tryParseDoubleResult);

            if (tryParseDouble)
            {
                return doublevar;
            }

            throw new Exception("Invalid data found. Cannot open.");
        }

Which would be great. Except for the following:

  • I built this in Win 7 Environment in VS 2008.
  • I've tested in Win7/ XP
  • When running in Win7 - the exception does not throw. I can even see that it should have, as I display the data it loads into a listbox in the app, but after loading the list is blank. If I step through the code line by line to the item where there is bad data, I can see the exception throw. But not in Debug if not debugging line by line, and not in Release either.
  • In XP the exception throws as expected.

This is obviously a problem having the application run in a state where there is problem with the data but no indication to user and it should not have let the user get this far IF there was a problem with the data.

Why isn't the exception throwing in Win7?


edit:

I think maybe the exception is being swallowed as I only see it thrown when stepping through line by line. What is the best way to check if it is being swallowed? Just follow my apps execution and look for a Try block? (It still doesn't exactly make sense when it throws properly in XP already, however...)

As a bit of extra, I have a start up window with 3 buttons. One is Open button. From here I open the data file to process.

var w = new Window1();
w.Show();

//At this point, FormLoad of all tabitems inside window1 execute, where the exception SHOULD throw. And in fact when it happens, nothing is thrown but the execution jumps from the line where the exception should throw to the line below Close(); and the next window loads but one screen out of three is empty because of the exception thrown because of the data.

Close();

edit1:

The class where the exception is thrown is Singleton, I don't know if this has anything to do with the problem...

edit2:

After several days further investigation, I'm still at a lost to why this is happening. Addressing the questions: yes I know I should make my own custom exception class. But this doesn't change what is happening here. I cannot find a try catch higher up the stack. I have an exception handler where if an exception is thrown in the application, it Environment.Exit(1); then logs the exception to text file. I have taken the exception handler out completely and yet still see the same behaviour.

It is not due to regional settings problem...

And anyway, all aside, this still does not explain why the exception is thrown as intended in XP (and the app crashes and logs exception to file) whereas in Win7 - the exception is ignored and execution continues.

A: 

Most likely your computers differ in their regional settings. For example thousand/decimal separators differ between countries, e.g "1,000.00" vs "1.000,00", DateTime formats differ, etc. Try using Parse/TryParse/ToString overloads which specify CultureInfo explicitly and avoid defaulting to computer's settings, perhaps by using CultureInfo.InvariantCulture.

repka
+1  A: 

I am assuming you are using tryparse here and rethrowing the exception just to demonstrate that try parse isn't working as expected... Why not try adding a Debug.Print inside you're if statement to see what you are getting.

Also, make sure this code isn't being called from another function that is wrapping this code with a try/catch block that is swallowing the exception

Steve Sheldon
+1  A: 

When you're stepping through in debug mode, you can see the exception getting thrown, right? What happens after that? That is, after the throw new Exception() line, where do you end up when you press F10? That's where the exception is being swallowed.

If you end up in framework code somewhere, it means you need to manually add a try...catch yourself in the code that processes the file:

void Form_Load(object sender, EventArgs e)
{
    try
    {
        ParseFile();
    }
    catch(Exception ex)
    {
        MessageBox.Show("The file was not valid: " + ex.Message);
    }
}
Dean Harding
See edit, After hitting F10, I end up after `w.Show();` There is no Try Catch block around this
baron
+1  A: 

First, you really should be throwing your own exceptions. System.Exception is the top-level exception from which all exceptions inherit. Consider creating a DataFormatException, for example - and throwing that.

Next, it sounds like you are likely catching System.Exception someone lower in the stack that is swallowing this exception. Again, it would be ideal if you only catch System.Exception at the lowest point in the stack for that thread, and use that as a catch-all for the whole application. In other places in your code, you should catch the exceptions that expect to happen. For example, the caller of your method should only trying to catch DataFormatException and ArgumentException (which you should throw if "doublevar" is null or empty). For example:

/// <summary>
/// Checks to see if the specified value is a double.
/// </summary>
/// <param name="valueToCheck">The value to check.</param>
/// <exception cref="ArgumentException">If <paramref name="valueToCheck"/>
/// is null or empty.</exception>
/// <exception cref="DataFormatException">If <paramref name="valueToCheck"/>
/// could not be parsed as a valid double.</exception>
private static double CheckDouble(string valueToCheck)
{
    if (string.IsNullOrEmpty(valueToCheck))
        throw new ArgumentException("Argument 'valueToCheck' cannot be null or empty.", "valueToCheck");

    double result;

    if (double.TryParse(valueToCheck, out result))
    {
        return result;
    }

    throw new DataFormatException("Value '" + valueToCheck + "' could not be parsed as a double.");
}

Hope that helps...

Robert Seder
Thanks for your answer. I am wondering however, is the only way the exception can be swallowed is by being inside a `try {}` block somewhere further up the stack? Could there be another scenario which would cause an exception to be swallowed?
baron
@baron - not really. When an exception occurs, it "falls" through the stack until it either finds a catch block that is suitable, or if it hits the last (the bottom) stack frame - that's when the application will crash with an unhandled exception. There must be someone in the callstack that is catching System.Exception
Robert Seder
AFAICT - this is not the case. I am not 100% sure about the exception handler, but if I comment that entirely, the same thing happens so I have no idea why this is getting swallowed, AND, only in this environment!?
baron
For a simple example: Main() is the first stack frame, it calls MethodA(), that calls MethodB(). If an exception happends in MethodB() and an appropriate catch block isn't there, the run-time "falls through" to MethodA(). If there is not appropriate catch block there, it falls through to Main(). If there is no appropriate catch block there, your application blows up. "Appropriate" means that you are catching an exception, or a super-class of that exception. System.Exception being the highest level super-class of ALL exceptions. Somewhere in your chain of calls, you are catching and swallowing.
Robert Seder
I have startup.xaml as the start up app, but there is a class called App.xaml which it looks like where it all starts... Anyway following through starting in start up, we have e.g. methodA calls methodB calls methodC. When the exception is thrown in methodC I fall through all the way back to startup, where there is no try catch. Then execution continues in startup, despite the fact the exception was thrown and the app only partially loaded. I will try a "lower" exception and see if anything changes
baron
I've changed to `ArgumentException`'s and can definitely confirm I am not catching them, but they are being ignored. I've done a search on `Try` on the entire code - its not there.
baron
If I'm debugging line by line, see the line where the exception happens, no exception info window pops up in Visual studio, pressing F11 to stepinto next line falls back to the startup part, IF there was a try catch handler, shouldn't my debugger step through that to show it there? It doesn't...
baron
Ahhh - dude! You didn't say this was WPF/Silverlight! Also, I have VS2010 + Win7 and for some reason, my exception debugging defaults to off for all projects. If you click on Debug menu, then Exceptions... "Common Language Runtime Exceptions" shoudl at least, be checked. If it's not, the debugger will NOT prompt you when an exception gets thrown, and will act exactly like you're describing! Secondly, since this is WPF/Silverlight, I'm not sure how it deals with an unhandled exception, normally. I assume you mean that you can't debug the exception, while running in debug mode?
Robert Seder