32

I would like some tool, preferably one that plugs into VS 2008/2010, that will go through my methods and add XML comments about the possible exceptions they can throw. I don't want the <summary> or other XML tags to be generated for me because I'll fill those out myself, but it would be nice if even on private/protected methods I could see which exceptions could be thrown. Otherwise I find myself going through the methods and hovering on all the method calls within them to see the list of exceptions, then updating that method's <exception list to include those. Maybe a VS macro could do this?

From this:

private static string getConfigFilePath()
{
    return Path.Combine(Environment.CurrentDirectory, CONFIG_FILE);
}

To this:

/// <exception cref="System.ArgumentException"/>
/// <exception cref="System.ArgumentNullException"/>
/// <exception cref="System.IO.IOException"/>
/// <exception cref="System.IO.DirectoryNotFoundException"/>
/// <exception cref="System.Security.SecurityException"/>
private static string getConfigFilePath()
{
    return Path.Combine(Environment.CurrentDirectory, CONFIG_FILE);
}

Update: it seems like the tool would have to go through the methods recursively, e.g., method1 calls method2 which calls method3 which is documented as throwing NullReferenceException, so both method2 and method1 are documented by the tool as also throwing NullReferenceException. The tool would also need to eliminate duplicates, like if two calls within a method are documented as throwing DirectoryNotFoundException, the method would only list <exception cref="System.IO.DirectoryNotFoundException"/> once.

Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
  • 4
    Note that such a tool is not trivial and can never guarantee to give you a complete list of exceptions, because a) code my be executed dynamically, e.g. using reflection, or b) the exception is thrown by the runtime such as an OutOfMemoryException, StackOverflowException etc... – Dirk Vollmar Jun 07 '10 at 13:39
  • 2
    Nor can this be exhaustive, as such a tool would have to both go through all the possible managed exception including those in the BCL and possibly know about the underlying com exceptions for code that does interop. – Oded Jun 07 '10 at 13:40
  • 2
    I'm curious as to why you want to do this. How would it make a difference to your calling code knowing or not knowing which exceptions might be thrown? – Christian Hayter Jun 07 '10 at 13:41
  • 5
    @Christian Hayter: It will be helpful to callers knowing what exceptions to expect. MSDN for instance documents this. – Dirk Vollmar Jun 07 '10 at 13:42
  • .NET best practice is not to swallow individual exception types in order to change the behaviour of the code you are calling. Instead, you should catch and log all exceptions at the highest level. If you control both a method and its caller, then there is no need to document what exceptions could be thrown because your calling code will *never* make use of that information. – Christian Hayter Jun 07 '10 at 13:56
  • If you don't control the calling code, then not documenting exceptions still has value because you then force the developer using your code to conform to best practices, rather than depend upon your internal code behaviour. – Christian Hayter Jun 07 '10 at 13:58
  • I'm guessing this would be possible to do only for systems where you have access to parse and scan all the source code. – FrustratedWithFormsDesigner Jun 07 '10 at 13:58
  • 1
    @FrustratedWithFormsDesigner: Strictly speaking, this is true of every (local, meaning no service references) .NET assembly. Even obfuscated IL could be analyzed (in fact, it could be analyzed without any additional difficulty) for exception handling. – Adam Robinson Jun 07 '10 at 14:08

4 Answers4

10

The long and the short answer is that this isn't possible. Unlike Java, none of the .NET languages require that functions report a list of possible exceptions that can be thrown (which means that you either have to catch or report any exceptions that could be thrown on functions that it calls). Because of this, there's no generic way to determine an exhaustive list of every exception that a function could throw (I'm using the word function here to cover anything that's written like a function, including operators, constructors, etc.) because you have no guarantee as to the exceptions that could be thrown by what a given function might call.

If you're willing to go in limited, then it's conceivable that you could write something that could scan MSDN for the appropriate article for a given .NET library call and use the list of exceptions there (if any) to recursively establish a list of what could possibly be thrown. This wouldn't, however, cover any third-party libraries or catch any exceptions thrown by the runtime (OutOfMemoryException, StackOverflowException, NullReferenceException [unless you want to take it a step further and have your exception analysis also determine if there is any possibility of a null reference, but this, too, seems impossible to do in a completely generic sense]).

I'm pretty sure that this has been covered a time or two by the C# team (I'd be surprised if Eric Lippert hasn't already answered a question about this on SO), but I'm pretty certain that it boiled down to this: While this sort of system is useful and valuable to some people, mandating its use (and forcing you either to report or catch all possibly thrown exceptions) led to a lot of try { ... } catch (Exception ex) { ... } blocks in order to avoid the housekeeping, and blanket, silent catches are a lot worse (IMHO) than an unreported exception.

Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
  • Is there a way of dynamically checking the list of exceptions in a method's XML comments? It'd be a cheap, non-exhaustive technique, but it'd be better than nothing/manually documenting exceptions. – Sarah Vessels Jun 07 '10 at 13:49
  • @Sarah: There is no such tool that I'm aware of, but I can't see why you could write something to read the XML documentation files for a given library. You'll have to perform your own static analysis and overload resolution (matching the rules from the C# spec; calling this non-trivial would be a gross understatement) in order to match up calls with documentation. – Adam Robinson Jun 07 '10 at 13:50
  • 2
    The problem with checking recursively only on comments is that you don't know what exceptions the top method catch()es. So, if A calls B, and B can throw all sorts of exceptions, you don't know whether those bubble up, or if they are caught. Any kind of static analysis will be useless without knowing the exact underlying code. So, if you do this, don't bother looking recursively; you must trust that method A() will correctly document all possible exceptions it can throw. – drharris Jun 07 '10 at 13:54
  • 2
    One does not simply recursively check method comments. Their black XML is guarded by more than just `catch` blocks. There is evil there that does not sleep. – Sarah Vessels Jun 07 '10 at 13:58
  • @drharris: While you're correct, I'm not sure what you're getting at. How could you possibly check recursively without access to the underlying code? Even if you're analyzing it via IL and not source code, you can still determine what exceptions are caught. While I think we're in agreement that this isn't worth the trouble (and is likely impossible in a completely generic sense, anyway), I'm not clear on how one could recursively analyze the code without access to the code. – Adam Robinson Jun 07 '10 at 13:58
  • @Adam Robinson: I think drharris means IL when taking about code. Without the IL (or the source code) and just XML comments you won't be able to know which exceptions have been handled already. – Dirk Vollmar Jun 07 '10 at 14:02
  • @0xA3: And what I'm saying is that without the IL, you can't check recursively at all (what do you intend to use to know what else to check?). My point is that a recursive check by its nature *requires* access to the code or IL, so there's no real use in talking about what to do when you're checking recursively without it. – Adam Robinson Jun 07 '10 at 14:06
  • 1
    The OP mentioned recursive analysis in the Update section. I merely wanted to point out that recursive analysis won't yield a proper indication of which exceptions bubble through without a very extensive algorithm (and IL access). And given XML comments only, you can't possibly know what bubbles through from called commands. It was a point of awareness, that any tool will not be 100% accurate. – drharris Jun 07 '10 at 15:27
  • @drharris: And, again, I'll make the point that *recursive analysis is 100% impossible without IL or source code access*. It's not a matter of "you really need this to do it right", it's a matter of "you need this or it's 100% impossible". Without IL or source access, *you do not know what functions are being called in order to perform a recursive search*. – Adam Robinson Jun 07 '10 at 15:28
  • The article you're looking for regarding the C# design team's opinions on checked exceptions is here: http://www.artima.com/intv/handcuffs.html – Eric Lippert Jun 17 '10 at 09:55
2

You can achieve part of your requirements by using AtomineerUtils which has support for documenting exceptions.

You can also use GhostDoc, Resharper and Agent Johnson Plugin for generating exceptions. See the following question: How to document thrown exceptions in c#/.net

Community
  • 1
  • 1
Giorgi
  • 30,270
  • 13
  • 89
  • 125
1

Exception Hunter from RedGate software will get you half-way there. It can do a static analysis of your code and show you what exceptions will be thrown by what lines of code -- including .NET Framework calls. It won't write the XML documentation for you.

But, I have to say, you need to be realistic about how useful such a tool would be... there are a number of exceptions that may happen as a result of extremely unusual circumstances, such as System.OutOfMemoryException and System.ExecutionEngineException, or as a result of programmer error, such as System.NotImplementedException. Technically, these are all possible, but realistically, attempting to document most of them for every method is not worth your time... you'd end up with hundreds of lines of comment for practically every method in your application.

Warren Rumak
  • 3,824
  • 22
  • 30
0

RedGate Exception Hunter does analyze code for possible exception. Maybe you could use some of its functionality.

Daniel Brückner
  • 59,031
  • 16
  • 99
  • 143