最近我遇到了一个我没想到的异常,因为在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文档我没有看到任何提及此异常。在例外部分中有:
更多地考虑这个问题,我想抛出的异常实际上应该是IOException而不是UnauthorizedAccessException。这是.NET Framework中的错误吗?问题是我有IOException处理程序,它通知用户无效的文件路径并继续应用程序工作流而不会崩溃。这个UnauthorizedAccessException崩溃了我的应用程序,因为它没有处理。
我该如何处理这类问题?我想我过去遇到了类似的无证异常问题,但这个问题确实激励我研究这个问题,并在这里提问。
答案 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,不应该抓住一般例外。
我们找到了为什么我们得到了错误的异常类型,并且在另一个异常中出现异常导致真正的异常逃避。
**获得异常就像在身体上疼痛一样。两者都说系统存在问题但是对于所有疼痛采取相同的药物是不好的,所以在这种情况下尝试捕获特定的例外。