Automating documentation of Exceptions - c#

In our solution we have a project that contains all the exceptions.
All of the exceptions inherit our base exception which inherits from ApplicationException.
Our base exception includes a field for exception number.
What I would like to do is to run a script that creates a list with exception name, number and xml documentation.
Any idea how to do this?

If you want to generate a list of the custom exceptions in your application, you can use XML comments for this task. See the accepted answer to this question. As far as I know, the comments will not be able to access the error number property, but you can add an XML comment to that property and state the error number there.

A "script" is not going to be able to do this. You need a static code analyzer that traces all the method calls and detects when an object that derives from Exception is created and thrown. It gets sticky when the code calls methods in the .NET framework, you don't have the source code for it. System.Reflection is no help, it cannot reflect code.
This ultimately goes back to why exception specifications are such a bad idea.
Redgate had a product named "Exception Hunter" to do this. But they gave up on it, couldn't make it reliable enough. The discontinuation announcement is here. Don't buy too much stock on them blaming .NET 4 for this.

Related

Get Specific information from thrown exception

Lets consider that we have an Exception ex thrown in the code. Now in the catch body, I want to have access to six pieces of information:
Solution Name
Project Name
NameSpace Name
File Name
Method Name
Line Number
What I already know is that using
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(e, true);
I can have access to some of these information(full path of file, line number, etc). But still this information is not all I need. For example, I do not know how to extract solution name or namespace name from trace. Apparently parsing the path for the file is also not an option because different errors can have several layers of file and folders hierarchy and one global rule does not work for all of the errors.
I wonder is there any way to have access programmatically to these info?
Many thanks.
In all likelihood you're not going to get something totally ideal for what you're asking for, but I'll share some tools and thoughts you might not have known about or considered:
There are some attributes (CallerFilePathAttribute, CallerLineNumberAttribute, and CallerMemberNameAttribute which, when added to an optional method parameter, will cause the compiler to automatically insert a default value based on the context of the code being compiled. You could create a helper method with attributes like this to capture the information you want.
There are tools like Fody, known as "IL Weavers", which can run after the main compile process and change the compiled code in a particular way. For example, your code could be written to make a simple call to one method, but when it's compiled the weaver could change the code to create a bunch of contextual information and pass it to a logging method.
If you're organizing your code well, you can often ensure that the namespace, class, and method (which are all captured as part of the stack trace) are enough information that you can guess the solution, project, and File Name.
When you're catching an exception, you typically want to either log what happened and handle the exception in a particular way, or simply wrap the exception in another exception with more contextual information. If you choose the latter, then the namespace, class, and method name will get included in the stack trace of the thrown exception. So when it's logged further up the stack you'll have access to that data.

Find all catches where exceptions could end up

I'm currently trying to find an error by reading code, since it is not reproducable at our end.
Nowadays it is easy to find definitions of members, methods, functions and all usages via Resharper, but in this instance I would like to have a function like: "From this line, give me all locations where an exception generated here could be caught"
Does such a function exist in Resharper, VS or any other place?
This thread appears relevant: Is there a free alternative to Exception hunter?
Specifically, you may find Microsoft Code Digger useful.

How can i know what kind of exception a class will throw?

is there any page from MSDN or somewhere can tell us, what kind of exception will be throw from a specific class?
for example, FtpWebRequest. how can i find out what kind of exception it will throw??
the page from MSDN is not really helpful
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest%28v=VS.100%29.aspx
Thanks
Classes don't throw exceptions. Members (Properties and Methods) do. So you need to look at the documentation for the individual members to know.
As others said, the intellisense will tell you. In addition, you could step into the framework code itself.
In addition, the documentation for each method contains the list of exceptions it might throw. Example.

C# explicitly defining what exceptions are thrown

In Java, you explicitly define what exceptions are thrown using the "throws" keyword. That way, anyone calling your method knows what to catch.
Is there something in C#? If not, how do I know what exceptions to catch, or how do I let others know what exceptions to catch?
Also, if I am defining an interface, is there a way to say "methodX() should throw this exception on error"?
There is nothing equivalent in C#: The Trouble with Checked Exceptions
Other than documentation, there is no way to declare an interface to say "methodX() should throw this exception on error".
C#/.net does not have checked Exceptions, they proved to be less useful in large scale systems than first thought. In a lot of projects the time to maintain the check exception specs was a lot greater than the debugging time saved by having them.
Checked Exceptions seem like a good ideal until you have methods that can take delegates or calls into object you pass in. Take a simple case, the Sort() method on a list can’t know what exceptions it will throw, as it does not know what exceptions the Compar() method on the objects being sorted will throw.
So the spec for the exceptions a method may throw must be able to include information on how exceptions are populated from pass in objects and delegates. No one knows how to do this!
However there are tools that you check if you are catching all exceptions – see Exception Hunter by Red Gate. I personally don’t see much value in these tool, however if you like checked exceptions you may find them useful. ==> Looks like Exception Hunter wasn't too useful, so Redgate discontinued Exception Hunter a long while ago:
This feature is not available in C#. You can make proper XML documentation (3 slashes ///) and state what exceptions are being thrown.
This will be picked up by the IntelliSense mechanism and will be visible for the users of the class/method before they use it.
C# does not support this. (Not that I know anyway).
What you can do is use Xml Comments so that while calling you methods this data will be shown by intellisense.
As far as I'm aware there is no throws declaration in C# you can document your method indicating that it throws an exception but no forced error handling.
C# doesn't support checked exceptions. The language designers consider checked exceptions in the way java uses them a bad idea.
Some workarounds
Let me cite this medium article: It's almost 2020 and yet... Checked exceptions are still a thing
Among the many reasons why it's a bad idea, putting the checked exceptions in the contract (interfaces):
makes it impossible to change the implementation of an interface with a different one which throws different exceptions
exposes implementation details
a change of the checked exceptions of an API interface, makes it necessary to change the whole chain of interfaces in the call stack
For example, imagine that you are implementing a repository based on SQL Server, so you expose all kind of SQL Server specific exceptions. Then you want to move it to MySQL or Cosmos BD. Of course:
the implementation can't be changed to a new one that need to throw different exceptions. Also related to this, if you have different implementations of the storage, you can't just change them by configuration, but you need to have different compilations of the code for each storage backend
this is the explanation for 1: as the interface showed the implementation details (SQL Server exceptions) know you can't just change it
if you need to make the change, prepare to change the interface at all levels, since the API that uses the database up to the lates consumer in the call stack chain.
The articles cited above includes pointers to many explanations to discourage the use of checked exceptions, included this by the creator of C#: The trouble with checked exceptions

How do I chose the most appropriate type of exception to throw?

There are already lots of questions on SO about exceptions, but I can't find one that answers my question. Feel free to point me in the direction of another question if I've missed it.
My question is quite simple: how do other (C#) developers go about choosing the most appropriate type of exception to throw? Earlier I wrote the following code:
if (Enum.IsDefined(enumType, value))
{
return (T)Enum.Parse(enumType, value);
}
else
{
throw new ArgumentException(string.Format("Parameter for value \"{0}\" is not defined in {1}", value, enumType));
}
I have since realised that throwing an InvalidEnumArgumentException would probably have been more appropriate had I known of its existence at the time.
Is there an authoritative resource available that helps developers chose exception types, or is it simply a matter of experience?
Edit
I've given the points to Noldorin for providing a range of ideas in a well thought-out answer. The points could have gone to any one of you really - thanks for all the suggestions.
Krzysztof Cwalina has a good post on this see chapter "1.1.1 Choosing the Right Type of Exception to Throw"
PS Consider subscribing to his blog. Good reading!
To answer your question: InvalidEnumArgumentException
because throw the most specific (the most derived) exception that makes sense.
AND callers that catch ArgumentException, catch InvalidEnumArgumentException too...
I would say it's just down to experience. There's still new exceptions I discover every so often, and I've been working with many aspects of .NET for a while now! What would you want this source to tell you, anyway? Choosing the appropriate exception type would seem highly context-specific, so I'm doubtful over the level of advice it could offer. Listing the more common ones would be most it could provide. The names and Intellisense descriptions of the exception types typically explain with good clarity their usage scenarios.
My recommendation is simply to familiarize yourself with all of the fundamental ones (specifically, those in System, System.IO, and any other namespaces you often use), and learn the others along the way. I find that I generally get away using just a small number. If you accidentally use a more generic exception type when there already exists a more specific one in the BCL, then it's no great crime, and can be changed later easily enough. To be honest, for any error that's particularly specific, you will often need to create your own class inheriting from Exception anyway.
Hope that helps.
Edit: If you want a brief guide to the very common ones, see the Common Exception Classes page on MSDN.
Common Exception Types and their Explanations
I think this will probably help you find out what the most appropriate exceptions for you to use are. You can also look into the MSDN documentation for more information on the Exception class and all of its types if you need.
MSDN Exception Class (System)
MSDN SystemException Class
(System) - More thorough list of
exception types
If you check out the MSDN article on System.Exception, right at the bottom of the page is a whole list of BCL exception types that inherit Exception. It's not quite a definitive list on what should be used for what - but it does give you a great place to start checking out exception types. Going through each will tell you what they should be used for:
http://msdn.microsoft.com/en-us/library/system.exception.aspx
There is also a fairly comprehensive article regarding the .NET Exception Hierarchy found at:
http://msdn.microsoft.com/en-us/library/z4c5tckx(VS.71).aspx
In fact the whole section in the MSDN library about handling and throwing exceptions is pretty good:
http://msdn.microsoft.com/en-us/library/5b2yeyab(VS.71).aspx
I have most of the common exceptions written on postcards on my desk and use them when people try and interop with me in a way that is exceptional.
This is really good practice for working out which exception fits best...
The one I find myself using mostly is OperationNotSupportedException
I think the real question is to ask yourself "What type of exception do I want to handle?" If you're not going to have special handling for an InvalidEnumArgumentException or an ArgumentException, then they offer no advantage over a plain old Exception.
I typically either throw Exception or wrap the exception in a custom exception.
Edited to add:
At one point, I recall that the guidance from Microsoft was that your application should never throw framework exceptions, rather it should only throw extensions of ApplicationException.
I usually define my own structure of exceptions, first creating some base exception:
class MyProjectNameException:Exception
{
...constructors, etc
}
and then derived classes for more precise exceptions. In this way you know exactly when to expect which exception, and you know if the exception was thrown by you or by the framework.
If you find an exception that is a good fit, you can use it.
If in doubt, just use ApplicationException. It's the exception that is intended for code that is not part of a standard library.
If the exception is not intended to be used in a standardised way (like catching the base class IOException to catch any I/O related error), the message that you put in the exception is more useful than the type of the exception.

Categories

Resources