Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to figure out which exceptions a certain method can throw if that is not documented in MSDN?

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:

  • ArgumentException - path is an empty string ("").
  • ArgumentNullException - path is null.
  • FileNotFoundException - The file cannot be found.
  • DirectoryNotFoundException - The specified path is invalid, such as being on an unmapped drive.
  • IOException - path includes an incorrect or invalid syntax for file name, directory name, or volume label.

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.

like image 523
matori82 Avatar asked Jan 16 '14 19:01

matori82


People also ask

How do you handle specific exceptions?

The order of catch statements is important. Put catch blocks targeted to specific exceptions before a general exception catch block or the compiler might issue an error. The proper catch block is determined by matching the type of the exception to the name of the exception specified in the catch block.

How do you handle exceptions in catch block?

You can put a try catch inside the catch block, or you can simply throw the exception again. Its better to have finally block with your try catch so that even if an exception occurs in the catch block, finally block code gets executed. Finally block may not get executed in certain exceptions.

Does throwing an exception return from a method?

Yes, throwing an exception causes the method to return immediately. However, it's not a normal return. For example, there is no return value. The only way to capture control from a method that is returning as a result of an exception being thrown, is to have an exception handler.

Which is the best way to handle errors in NET?

You can handle default errors at the application level either by modifying your application's configuration or by adding an Application_Error handler in the Global. asax file of your application. You can handle default errors and HTTP errors by adding a customErrors section to the Web. config file.


Video Answer


5 Answers

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

like image 98
JaredPar Avatar answered Oct 16 '22 18:10

JaredPar


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;
     }
}
like image 23
rae1 Avatar answered Oct 16 '22 19:10

rae1


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.

like image 24
evanmcdonnal Avatar answered Oct 16 '22 19:10

evanmcdonnal


I read this before... may it will give you some insight. Microsoft Program Manager wrote this in a blog.

like image 1
Adi Barman Avatar answered Oct 16 '22 19:10

Adi Barman


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.

like image 1
sunnytyra Avatar answered Oct 16 '22 18:10

sunnytyra