如果MSDN中没有记录,如何确定某个方法可以抛出哪些异常?

时间:2014-01-16 19:22:33

标签: c# .net exception exception-handling msdn

最近我遇到了一个我没想到的异常,因为在MSDN中没有记录它可以被特定的构造函数抛出。所以这是引发异常的C#行:

    using (StreamReader sr = new StreamReader(filePath))

filePath here是应该包含某个文件的完整路径的字符串。问题是我的“filePath”变量实际上是文件夹的路径,而不是文件的路径。因此构造函数StreamReader(filePath)抛出:

System.UnauthorizedAccessException: Access to the path 'D:\testFolder' is denied.

好的,所以这显然是一个错误,我通过传递正确的路径来修复它...但是查看StreamReader(string)的MSDN文档我没有看到任何提及此异常。在例外部分中有:

  • ArgumentException - path是一个空字符串(“”)。
  • ArgumentNullException - 路径为空。
  • FileNotFoundException - 找不到该文件。
  • DirectoryNotFoundException - 指定的路径无效,例如位于未映射的驱动器上。
  • IOException - 路径包含文件名,目录的语法不正确或无效 名称或卷标。

更多地考虑这个问题,我想抛出的异常实际上应该是IOException而不是UnauthorizedAccessException。这是.NET Framework中的错误吗?问题是我有IOException处理程序,它通知用户无效的文件路径并继续应用程序工作流而不会崩溃。这个UnauthorizedAccessException崩溃了我的应用程序,因为它没有处理。

我该如何处理这类问题?我想我过去遇到了类似的无证异常问题,但这个问题确实激励我研究这个问题,并在这里提问。

5 个答案:

答案 0 :(得分:7)

不幸的是,实际上没有办法以一般方式处理这个问题。 C#和CLR的本质使得确定可以从方法抛出的全部异常(如果不是完全不可能的话)变得困难。有一些简单的API是可能的,但一般来说不是。

我处理这个问题的方法就是抓住Exception。 CLR的最新版本使得默认情况下无法捕获危险的异常。因此,您只会捕获更安全的例外。除非你想对一个非常具体的错误做出反应,否则只需捕获所有错误并采取适当的操作,使API调用失败

答案 1 :(得分:3)

虽然你不能事先100%意识到一种方法可以抛出哪种类型的异常,但是有一些方法可以避免为这个问题祈祷,这确实是CLR所缺少的,你遵循一个共同的模式,这是捕获从Exception派生的所有异常,然后进一步区分哪些可以处理,哪些不可以,

try
{
}
catch (FileNotFoundException)
{
}
catch (DirectoryNotFoundException)
{
}
catch (IOException)
{
}
catch (Exception exception)
{
    // For the ones you do not know how to handle, at least document it and throw
    log(exception);
    throw;
}

它将使您的调试更容易。

要意识到这个模式将基于层次结构,其中更多派生的异常类型应该首先出现,否则您可能会首先执行较少派生的catch。换句话说,不要这样做,

try
{
}
catch (IOException)
{
     // Will get executed for both DirectoryNotFoundException and
     // FileNotFoundException even though you specified specific ways to 
     // handle these types
}
catch (DirectoryNotFoundException)
{
}
catch (FileNotFoundException)
{
}

或者,您只能抓住Exception并使用if来测试实际类型,这不是很漂亮,但可能更灵活,

try
{
}
catch (Exception exception)
{
     if (exception.GetType() == typeof(IOException))
     {
     }
     else if (exception.GetType() == typeof(DirectoryNotFoundException))
     {
     }
     else if (exception.GetType() == typeof(FileNotFoundException))
     {
     }
     else
     {
         log(exception);
         throw;
     }
}

答案 2 :(得分:2)

我认为无论如何都看不到方法可能抛出的所有可能异常。事实上,你必须通过所有方法调用来获取该列表并且这不会发生。

就个人而言,我对异常处理的感受更像Joel Spolsky(http://www.joelonsoftware.com/items/2003/10/13.html);我很少捕获特定的异常,并尽可能避免使用try-catch。在这种情况下,我会使用catch (Exception e)来避免这个问题然后我会使用if-else来尽可能恰当地处理不同的类型。

答案 3 :(得分:1)

我之前读过这篇文章......可能会给你一些见解。 Microsoft程序管理器在blog中写了这个。

答案 4 :(得分:1)

在各种情况下,microsoft会提供不正确的异常或异常,这些异常或异常在某些方法的msdn中未提及。我也遇到了类似的情况,我必须捕获一般异常来代替特定的异常(在我的情况下是system.formatexception)。

但是你可以面对诸如避免静态FxCop违规等问题。根据fxcop,不应该抓住一般例外。

我们找到了为什么我们得到了错误的异常类型,并且在另一个异常中出现异常导致真正的异常逃避。

**获得异常就像在身体上疼痛一样。两者都说系统存在问题但是对于所有疼痛采取相同的药物是不好的,所以在这种情况下尝试捕获特定的例外。