Reputation: 3829
Recently I got got an exception that I wasn't expecting because it wasn't documented in MSDN that it can be thrown by the particular constructor. So here is the C# line that threw exception:
using (StreamReader sr = new StreamReader(filePath))
filePath here is the string that should contain full path to a certain file. The problem was that my "filePath" variable was actually a path to the folder and not to the file. Because of this the constructor StreamReader(filePath) threw:
System.UnauthorizedAccessException: Access to the path 'D:\testFolder' is denied.
Ok so this was obviously a bug and I've fixed it by passing a correct path... but looking at the MSDN docs for StreamReader(string) I don't see any mentioning of this exception. Under exception section there are:
Thinking some more about this issue, I guess the exception thrown should actually be IOException and not UnauthorizedAccessException. Is this a bug in .NET Framework? The problem is that I had IOException handler in place that notifies user about invalid file path and continues application workflow without crashing. This UnauthorizedAccessException crashed my application because it was unhandled.
How should I deal with this kind of issues? I think I encounter similar problem of undocumented exceptions in the past but this one really motivated me to research this issue and ask question here.
Upvotes: 8
Views: 368
Reputation: 89
There are various scenarios where microsoft gives incorrect exceptions or exceptions which are not mentioned in msdn for certain method. I also faced similar situation where I have to catch General Exception in place of specific exception(system.formatexception in my case).
But then you can face issues like, avoiding static FxCop violation. According to fxcop one should not catch general exception.
We found the reason why we are getting wrong exception type and it was Exception inside another exception causing the real exception to evade.
**Getting exception is like getting pain in body. Both tells that there is issue in the system but taking same medicine for all pains is not good so try to catch specific exception in this case.
Upvotes: 1
Reputation: 6144
Although you cannot before hand be 100% aware of which types of exceptions a method can throw, there are ways to avoid falling pray to this issue, which is indeed something missing from the CLR, you follow a common pattern, which is to catch all exceptions derived from Exception
, and then further discriminate which you can handle and which you cannot,
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;
}
It will make your debugging a lot easier.
Do realize that this pattern will go base on hierarchy, where the more derived exception types should go first, or you risk the less derived catch
being executed first. In other words don't do this,
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)
{
}
Alternatively, you could catch only Exception
and use an if
to test for the actual type, which isn't as pretty, but might be more flexible,
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;
}
}
Upvotes: 3
Reputation: 13
I read this before... may it will give you some insight. Microsoft Program Manager wrote this in a blog.
Upvotes: 1
Reputation: 48096
I don't think there is anyway to see all of the possible exceptions that could be thrown by a method. The fact of the matter is, you would have to recurse through all method calls to obtain that list and that just isn't going to happen.
Personally my feelings on exception handling are more along the lines of Joel Spolsky (http://www.joelonsoftware.com/items/2003/10/13.html); I rarely catch specific exceptions and I try to avoid using try-catch as much as is reasonably possible. In this case, I would be using catch (Exception e)
to avoid this problem then I would use an if-else to handle different types as appropriately as possible.
Upvotes: 2
Reputation: 754745
Unfortunately there is really no way to deal with this problem in a general fashion. The nature of C# and the CLR makes it difficult, if not outright impossible, to determine the full set of exceptions that can be thrown from a method. There are some simple APIs where it is possible but generally speaking its not.
The way I handle this is to simply catch Exception
. Recent versions of the CLR make it impossible to catch dangerous exceptions by default. Hence you're only going to be catching safer exceptions. Unless you want to react to a very specific fault just catch all and take the appropriate action for the API call failing
Upvotes: 7