Through recent error-logging that I added to TruckWars, I found out the sometimes this line would fail:
double x = Convert.ToDouble("12.5");
The input string was static (not user input) as it came from an xml config file. The line threw this exception:
System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options,
NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
at System.Double.Parse(String s, NumberStyles style, NumberFormatInfo info)
at System.Convert.ToDouble(String value)
At first I thought "of course '12.5' is a valid double." And of course it worked on my machine, and all the servers I was checking. But, the logs still showed this occasional error. Then I thought - what if it's a globalization problem? In other words, for the "en-US" culture, "12.5" is a valid number, but not for other cultures. For example, this would fail for someone in France, where "12,5" is used for a decimal place (note the comma instead of the period).
So, I set up a unit test to check for a different culture:
public void ParseFromString_Global_Decimal()
System.Globalization.CultureInfo culture =
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
//run my parsing method here
//ensure that culture wasn't overridden:
And the test failed with the exact error that I expected. I could then fix it by passing in a specific culture (like "en-US") NumberFormat:
private static System.Globalization.NumberFormatInfo _formatNumber =
//essentially fixed by this:
double x = Double.Parse("12.5", _formatNumber);
I don't normally get this error because for our ASP.Net apps I use a set of utilities that already handled this, and I didn't need to worry about international users for the windows forms because I only make those for internal development tools. However, it's another reminder why it's nice to have logging for even simple apps.