C# CryptographicException not being caught

本文关键字:caught being not CryptographicException | 更新日期: 2023-09-27 17:57:52

我有一个名为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。我最初有一个try/catch,它有两个catch,一个用于CryptographicException,另一个用于SerializationException。那没用。我替换它以捕获Exception。最后,我明白了。

我不知道为什么,但出于某种原因,它似乎抓不住这个?我确信答案很明显,但我就是看不出来

我知道有些异常是不可覆盖的,比如StackoverflowException。我怀疑CryptographicException不是不可捕获的。

C# CryptographicException not being caught

您的ApplicationException没有"占据优先权"的原因是因为CryptographicException是从try/catch块外部抛出的。

换句话说,Deserialize并不是唯一可以抛出CryptographicException的API。您只需要放大try/catch/finally块,以包含所有可能引发异常的API调用。完成此操作后,ApplicationException将是Load可以抛出的唯一可能的异常,并且您的代码应该按预期工作。

为什么会遇到ApplicationException?如果您捕获了Exception,那么您应该捕获该异常。

根据您的注释,看起来异常是在某个流构造函数中抛出的。如果你把try-catch放在更多的代码周围,你会很好地捕获它。