I have a method that accepts random data at runtime (it could be string
, int
, etc.) and then it tries adding this data to a list of a random type (eg List<byte>
, List<int>
, etc.).
Due to the unpredictable nature of this, I have added 2 error handling routines. One to catch a FormatException
error and do some specific actions to fix the data. And secondly, I've also added a general catch-all for Exception
so if another error I'm not expecting is thrown, I can display the details and exit the application gracefully.
The weird issue I'm having (or at least it seems weird to me), is that whenever a FormatException
error is thrown, my Catch (FormatException ex)
does nothing and instead the error is being caught by Catch (Exception ex)
. So rather than being able to handle the error properly, the application exits instead.
To help isolate this, I've created a small example C# WinForms program that replicates the issue.
Here's the main form code:
private void button1_Click(object sender, EventArgs e)
{
// This works normally
ErrorClass.TestCatchFormatException<string, string>("abc", "def");
// This also works normally
ErrorClass.TestCatchFormatException<int, int>("123", "456");
// This should raise a FormatException error but only Exception catches it???
ErrorClass.TestCatchFormatException<int, string>("abc", "456");
}
And here's the code for my 2 classes:
public class DataClass<T, U>
{
public T Data1 { get; set; }
public U Data2 { get; set; }
}
public static class ErrorClass
{
public static void TestCatchFormatException<T, U>(dynamic inputString, dynamic inputString2)
where T : IComparable<T>
where U : IComparable<U>
{
try
{
List<DataClass<T, U>> theList = new List<DataClass<T, U>>();
TypeConverter converter1 = TypeDescriptor.GetConverter(typeof(T));
TypeConverter converter2 = TypeDescriptor.GetConverter(typeof(U));
theList.Add(new DataClass<T, U>
{
Data1 = converter1.ConvertFrom(inputString.ToString()),
Data2 = converter2.ConvertFrom(inputString2.ToString())
});
MessageBox.Show(
"Data1 Value is: " + theList[0].Data1.ToString() + "\n"
+ "Data1 Type is: " + theList[0].Data1.GetType().ToString() + "\n"
+ "Data2 Value is: " + theList[0].Data2.ToString() + "\n"
+ "Data2 Type is: " + theList[0].Data2.GetType().ToString());
}
catch (FormatException ex)
{
// Catches nothing for some reason
MessageBox.Show("Caught FormatException\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
catch (Exception ex)
{
// This catches the error but InnerException says the error is of type FormatException.
// Yet FormatException doesn't catch it???
MessageBox.Show("Caught Exception\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
}
}
Even weirder is that when I look at the InnerException the catch-all Exception
generates, it says this:
System.FormatException: Input string was not in a correct format.
So it is detecting it as a FormatException
error. Yet for some reason, catching FormatException
does nothing and only Exception
can catch it.
Does anyone know what I'm doing wrong here?
Your FormatException
is being wrapped in some other Exception
type. That's why the .InnerException property has a FormatException
. Try calling .GetType on the exception you are getting to see the wrapping type, and catch that instead.
BaseNumberConverter.ConvertFrom()
internally calls a helper function to throw an exception:
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
...
catch (Exception e) {
throw FromStringError(text, e);
}
}
return base.ConvertFrom(context, culture, value);
}
The implementation of FromStringError
is:
internal virtual Exception FromStringError(string failedText, Exception innerException) {
return new Exception(SR.GetString(SR.ConvertInvalidPrimitive, failedText, TargetType.Name), innerException);
}
So it throws an Exception
that wraps the actual FormatException
and adds some additional information (namely the value it's trying to convert and the type it's trying to convert to). Why it doesn't throw another FormatException
I don't know.
Prior to C# 6 there was no way to create a catch
that would catch based on the InnerException
. You'd have to catch Exception
and inspect the InnerException
type to handle it differently.
With C# 6 you can use an exception filter:
catch (Exception ex) when (ex.InnerExcpetion is FormatException)
{
// Catches nothing for some reason
MessageBox.Show("Caught FormatException\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
catch (Exception ex)
{
// This catches the error but InnerException says the error is of type FormatException.
// Yet FormatException doesn't catch it???
MessageBox.Show("Caught Exception\n\n" + ex.Message + "\n\n" + ex.InnerException);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.