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? Если вы ловите с помощью исключения, вы должны поймать исключение.

Учитывая ваш комментарий, похоже, что исключение выдается в одном из конструкторов потока. Если вы попытаетесь поймать больше кода, вы поймете, что все в порядке.

Другие вопросы по тегам