12

I'm not looking to implement the Java "throws" keyword. See http://www.artima.com/intv/handcuffsP.html for a discussion on the merits of the throws keyword and why it was not implemented in C#.

I am, however, curious if there's a way to create an attribute like the following:

[ThrowsException( exceptionType = NullReferenceException )] 
[ThrowsException( exceptionType = AuthenticationException )]
public void Login( Credentials credz ) 
{
    // ... etc...
}

such that - when calling a method which has been decorated with one or multiple ThrowsException attributes, the type of exceptions thrown by said method (at least the ones that are explicitly declared by the ThrowsException attribute) would be visible in the method's documentation

This is not the same as the Java "throws" keyword as it would not require that the caller handle these exceptions. Doing so could introduce breaking changes e.g. in a client application that does not handle new exceptions introduced by a version change.

While one could use:

/// <exception cref="member">description</exception>

My intent for using attributes is so that the project does not compile if the name of the exception has been changed or if the exception no longer exists. Therefore, How To Document Thrown Exceptions, is not the same question.


Update: 2013-05-23

I've figured out a way to resolve via the use of an attribute and without the use of plug-ins. I will try to get around to it this weekend and will be happy to post the solution if it works as expected. If someone beats me to posting a solution, I will happily accept their answer.

Since I won't be able to get around to this until Monday, I'm offering a bounty if you can beat me to it - An acceptable answer would:

  • ( not include the use of a visual studio plug-in or any third-party tool
  • && provide a way to include the exception(s) in the XML documentation
  • && ensure type safety is enforced during compilation )
  • || prove it is not possible to meet the preceding three requirements in order to provide a solution to the problem posed in this question

I would consider it acceptable for the XML documentation not to reflect the exceptions, from the ThrowsException attributes, until after the project has been built.

It would be interesting to see a Resharper-based solution (since it is common to most of the development shops I have worked in), but it will not be accepted if there is a solution that remains agnostic of third-party tools. Similarly, a solution that works only in Visual Studio would be accepted over a solution dependent on Resharper, but it would not be accepted if there is a solution that would work in other IDEs e.g. MonoDevelop (more frameworks supported - even better).

jeromej
  • 10,508
  • 2
  • 43
  • 62
Jordan
  • 5,085
  • 7
  • 34
  • 50
  • 1
    You mean like this? http://stackoverflow.com/questions/461306/how-to-document-thrown-exceptions-in-c-net – shriek May 22 '13 at 19:32
  • I have added clarity, apologies for the confusion – Jordan May 22 '13 at 20:40
  • XML comments will be added to the XML docs by default. You are going to need a VS add-in to make attributes visible in intellisense. There are some decent SO questions on writing that sort of thing already. – Yaur May 22 '13 at 20:46
  • This question should not be closed, it was marked as a duplicate of http://stackoverflow.com/questions/461306/how-to-document-thrown-exceptions-in-c-net while I explicitly stated how that is not the case – Jordan May 23 '13 at 17:02

3 Answers3

16

In C# you document classes and their members with a XML documentation. In Visual Studio, start typing slashes over something and by the third slash it'll auto-generate the most common tags for you to fill in. It looks vaguely like Javadoc and JSDoc.

You are looking, specifically, for the <exception> tag.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Geeky Guy
  • 9,229
  • 4
  • 42
  • 62
  • I must apologize for my lack of clarity.. I will modify the question - my intent for using attributes is so that the project would not compile if the name of the exception has been changed or if the exception no longer exists – Jordan May 22 '13 at 20:33
  • @Martin If you write e.g. `/// Why it's thrown.`, and if you actually build the XML docs when you compile your project, then you will get a compile-time error if no class called `DivideByZeroException` exists in the namespaces in scope. – Jeppe Stig Nielsen May 22 '13 at 20:46
  • @JeppeStigNielsen - maybe there's another option I would need to set, but I am generating the XML docs and it is compiling without issue – Jordan May 22 '13 at 21:00
  • @Martin Do you do as in the section _To set this compiler option in the Visual Studio development environment_ on the page [/doc (C# Compiler Options)](http://msdn.microsoft.com/en-us/library/3260k4x7.aspx)? – Jeppe Stig Nielsen May 22 '13 at 21:13
  • I've tried project properties -> build -> output -> XML documentation file and I've tried debug -> start options -> command line arguments: /doc and all possible permutations. The MS documentation is terrible. – Jordan May 22 '13 at 23:59
  • @JeppeStigNielsen it is [Warning CS1574 (Level 1)](http://msdn.microsoft.com/en-us/library/26x4hk2a.aspx), not an error. – Sam Harwell May 31 '13 at 01:36
  • 1
    @280Z28 You are right. The Original Poster can choose to treat this specific warning as an error, or treat _all_ warnings (possibly all warnings above some level) as errors. See this [MSDN page on warning level](http://msdn.microsoft.com/en-us/library/thxezb7y.aspx) for information on how that is done either from the command line or inside Visual Studio. – Jeppe Stig Nielsen May 31 '13 at 12:08
11

My intent for using attributes is so that the project does not compile if the name of the exception has been changed or if the exception no longer exists. Therefore, How To Document Thrown Exceptions, is NOT the same question.

You can do this without using attributes, instead by writing <exception> documentation and configuring your project like this:

Project properties -> 'Build' tab:
'Output' section: Check 'XML documentation file'.
'Treat warnings as erros' section: Check 'Specific warnings' and add warning 1574.

This way project won't compile if XML documentation cref attribute value cannot be resolved.

Stipo
  • 4,566
  • 1
  • 21
  • 37
  • This is the best answer so far, and I will accept if there are no better answers by the time the bounty ends in 6 days. A few issues I have with this: 1. it's specific to Visual Studio 2. it needs to be applied at the project level 3. This applies to all comments with cref statements e.g. I am developing a WPF project where I am using Data Annotations from MVC and I have a comment explaining that you can use the AspMvcActionAttribute for custom wrappers similar to which is obviously not referenced. – Jordan May 26 '13 at 17:45
  • 1. it is not specific to Visual Studio, you can also specify all these options directly in C# compiler. 2. Correct, it applies to compilable unit, which is project. 3. Correct, it applies to all comments with cref attribute. But why use cref attribute with something which is not referenced? Compiler cannot help with verifying if value is correct, nor documentation tool can't generate a hyperlink to a cref value. – Stipo May 26 '13 at 20:20
  • @Martin Regarding your item 3: You can add a project reference to `System.Web.Mvc.dll` so the `cref` is resolved while generating documentation. If you don't reference any members of that assembly from your code, then the final compiled assembly will actually omit the reference so you won't be left with an unwanted assembly... [comment too long so see next one...] – Sam Harwell May 31 '13 at 13:58
  • 2
    @Martin [...continued from previous] To prevent accidentally creating references to this assembly from code, set the `Aliases` field in the Visual Studio Properties pane for the reference to something like `mvc`. In the specific file that needs to reference this assembly in the documentation, add `extern alias mvc;` to the top of the file and then document to reference with ``. – Sam Harwell May 31 '13 at 13:59
  • Well while I still think there's a better way to do this in code I've been working 16 hour days for the past two weeks so I don't have time to get around to it... so bounty goes to you :) Pretty easy bounty question if you ask me ;) but I've never posted a bounty so I thought it would be fun. – Jordan May 31 '13 at 14:29
  • @280Z28 - Thanks for the useful addition. On a side note, I haven't had a need to use ANTLR yet, but I've seen it come in handy in some pretty awesome open source projects :) – Jordan May 31 '13 at 14:36
  • @Martin I agree, it was pretty easy bounty. Sorry that I couldn't give more satisfying answer. – Stipo May 31 '13 at 14:55
1

The below should work

[ThrowsException( ExceptionType = typeof(NullReferenceException) )]

Your attribute will have a property of type Type

Type ExceptionType { get; set; }
Jakub Konecki
  • 45,581
  • 7
  • 87
  • 126
  • 2
    Implementing the attribute is trivial. The challenge is making it do something useful. – Yaur May 22 '13 at 19:38
  • 1
    I see no reason for the downvotes since he addressed the OP's question. – Brian May 22 '13 at 19:43
  • "when calling a method which has been decorated with [a] ThrowsException attribute, the type of exceptions thrown by said method ... would be visible in the method's documentation" – Yaur May 22 '13 at 20:28
  • @Yaur - yes, and what it means? – Jakub Konecki May 22 '13 at 20:34
  • @JakubKonecki My assumption would be that he wants them visible in standard xml docs/intellisense. – Yaur May 22 '13 at 20:47
  • @Martin - my solution will give you type safety - if you delete / rename custom exception class than your project won't compile. – Jakub Konecki May 23 '13 at 00:49
  • @Jakub - this does not answer my question - I recognize that an attribute can be used to enforce type safety .. that's why I want to use an attribute – Jordan May 23 '13 at 17:04