C# CryptographicException не перехватывается
У меня есть сериализуемый класс с именем DataSet, который имеет статический метод Load(string filename, string password)
который возвращает десериализованный DataSet.
Вот:
public static DataSet Load(string filename, string password)
{
if (!File.Exists(filename))
throw new FileNotFoundException("File not found.", filename);
DataSet ds;
ICryptoTransform ct = Encryption.getDecryptor(password, salt, iv);
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
using (CryptoStream cs = new CryptoStream(fs, ct, CryptoStreamMode.Read))
{
using (GZipStream zs = new GZipStream(cs, CompressionMode.Decompress))
{
try
{
ds = (DataSet)new BinaryFormatter().Deserialize(zs);
return ds;
}
catch
{
throw new ApplicationException("This password cannot be used to decrypt this file. Either the password is incorrect or the file is corrupt");
}
finally
{
zs.Close();
}
}
}
}
}
И я называю это так:
try
{
dataSet = DataSet.Load(ofd.FileName, ep.Password);
}
catch (ApplicationException ae)
{
MessageBox.Show("Error:\r\n" + ae.Message, "Authorisation Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
}
С правильным паролем все работает нормально. Я проверяю это с неверным паролем. Ожидаемый результат - всплывающее окно MessageBox, говорящее "Этот пароль не может быть использован для расшифровки этого файла [...]". Вместо этого я получаю окно с неперехваченным исключением.
Если я отлаживаю в VS, я вижу, что произошло необработанное исключение CryptographicException. Первоначально у меня была попытка / уловка с 2 уловами, одна для CryptographicException и одна для SerializationException. Это не сработало. Я заменил его, чтобы поймать исключение. Наконец-то я поймал всех.
Я не знаю почему, но по какой-то причине это не может понять это? Я уверен, что ответ очень очевиден, но я просто не вижу его.
Я знаю, что некоторые исключения неуловимы, такие как StackruException. Я подозреваю, что CryptographicException не является неуловимым.
2 ответа
Причина в том, что ваш ApplicationException
не "имеет приоритет", потому что CryptographicException
выбрасывается извне try/catch
блок.
Другими словами, Deserialize
это не единственный API, который может бросить CryptographicException
, Вам просто нужно увеличить свой try/catch/finally
блок, чтобы охватить все вызовы API, которые могут вызвать исключение. После того как вы сделали это, ApplicationException
будет единственным возможным исключением, что Load
может скинуть и твой код должен работать как положено.
Почему вы ловите с ApplicationException? Если вы ловите с помощью исключения, вы должны поймать исключение.
Учитывая ваш комментарий, похоже, что исключение выдается в одном из конструкторов потока. Если вы попытаетесь поймать больше кода, вы поймете, что все в порядке.