Is there a way to make Visual Studio tell me which parts of my code may throw exceptions? Something like the compiler warnings that can be suppressed, but instead it warns me that some line may throw an exception if it isn't surrounded by a try and catch.
No, there is no such functionality in VS.
C# (and .Net in general) does not support any kind of annotation to specify "method throws an interesting exception" (unlike Java, see Why are Exceptions not Checked in .NET?). As result there is no way to have general tool that will let you know that some "interesting" exception ( IOException as you've suggested) can be thrown from any given method.
In some cases VS/C# compiler can help. I.e. in C# 8 NRE actually has partial special treatment - "nullable reference type" which lets compiler to know if code expects null or not and warn at compile time if null passed where it is not supposed to.
Note: XML documentation (which is mentioned in comments as source of intellisense tooltips) is not part of code and there is no requirements for it to be correct/complete. Wast majority of the code does not have any useful XML documentation and documentation is not necessary available at compile time. So while it may serve as basis for some tool I don't believe VS is using it for any code highlighting.
ReSharper usually does that. It adds some warnings for possible exceptions.
If you don't want to use it search for similar products.
Related
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.
One thing I find very frustrating with C# is when I find some issue and I want to throw a meaningful exception. I find it very difficult to find those exceptions in intellisense. There is no Exception namespace, so I cant list all exceptions via intellisense without digging around looking for the exception.
I am not looking to create my own exceptions, I am only trying to see if there are any other options than googling an exception to find its namespace so I can use it.
For the most part, this is bad practise. There are a small handful of exceptions that you should reuse (InvalidOperation, NullReference, ArgumentException, a few others). But you should not, for example, throw SqlException yourself - because you don't know what the framework might do with it.
Creating your own exception hierarchy adds meaning to your application at times of error. Reusing exceptions that have already-understood meanings leads to confusion - loss of meaning.
You can browse the entire Exception Class Tree in object Browser. Look for System.Exception and then click derived types. not 100% sure if all of them are there but the most of them are there for sure.
System.Exception -> Derived types (also in the root of the System.Excecption tree)
You can find some exceptions in the MSDN, here.
In general, these are the exceptions you'll ever tend to throw, and in many cases, you'll derive your own exceptions from these exceptions. However, a single method throwing too many different exceptions is generally frowned upon.
Also, recall the <exception> xml documentation tag. Using this tag goes a long way towards enlightening users which exceptions your method throws, and when. It's probably more important, in terms of clarity, than throwing exceptions of specific classes.
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
Is there a way to output a warning in the debugger if a certain method is used in the code? I have a couple of delicate methods that should only be used in exceptional cases, so I'd like to have some kind of warning output if they are actually called anywhere in the project.
Is this possible?
You should consider using the Obsolete attribute. It allows you to mark a method which should not be used. It takes two optional parameters a message and a flag indicating if the complier should fail or raise a warning.
You can use the Debugger.WriteLine method to see messages in the Debugger
Debugger.WriteLine("Don't use this method");
This is easily missed or ignored though. A more aggressive way of preventing this may be an assert.
Debugger.Fail("Are you sure you want to use this method?");
Yet another way to achieve this would be to mark the method as deprecated. This will result in a warning at compile time vs. debug time. You mentioned there are several places where it can be validly used. In those cases you could suppresse the deprecation warning with a pragma. This means only new uses of the method would cause a compile time warning which sounds like what you're after.
If I need to throw an exception from within my application which of the built-in .NET exception classes can I use? Are they all fair game? When should I derive my own?
See Creating and Throwing Exceptions.
On throwing built-in exceptions, it says:
Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.
and
Do Not Throw General Exceptions
If you throw a general exception type, such as Exception or SystemException in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle.
Instead, either throw a more derived type that already exists in the framework, or create your own type that derives from Exception."
This blog entry also has some useful guidelines.
Also, FxCop code analysis defines a list of "do not raise exceptions" as described here. It recommends:
The following exception types are too general to provide sufficient information to the user:
System.Exception
System.ApplicationException
System.SystemException
The following exception types are reserved and should be thrown only by the common language runtime:
System.ExecutionEngineException
System.IndexOutOfRangeException
System.NullReferenceException
System.OutOfMemoryException
So in theory you can raise any other framework exception type, providing you clearly understand the intent of the exception as described by Microsoft (see MSDN documentation).
Note, these are "guidelines" and as some others have said, there is debate around System.IndexOutOfRangeException (ie many developers throw this exception).
On the subject of System.Exception and System.ApplicationException: The latter was meant to be used as the base class of all custom exceptions. However, this hasn't been enforced consistently from the beginning. Consequently, there's a controversy whether this class should be used at all rather than using System.Exception as the base class for all exceptions.
Whichever way you decide, never throw an instance of these two classes directly. It's actually a pity that they aren't abstact. For what it's worth, always try using the most specific exception possible. If there is none to meet your requirement, feel free to create your own. In this case, however, make sure that your exception has a benefit over existing exceptions. In particular, it should convey its meaning perfectly and provide all the information necessary to handle the situation in a meaningful manner.
Avoid to create stub exceptions that don't do anything meaningful. In the same vein, avoid creating huge exception class hierarchies, they're rarely useful (although I can imagine a situation or two where I would use them … a parser being one of them).
I use the ArgumentException (and its “friends”) regularly.
NotSupportedException and NotImplementedException are also common.
My advice would be to focus on two things:
Scenarios
User expectations
In otherwords, I would sit down and identify:
Under what scenarios do you want to throw exceptions.
In those scenarios, what would the users of your API expect
The answer to #1 is, of course, application specific. The answer to #2 is "what ever similar code they are already familiar with does".
The behavior that comes out of this is:
Under the scenarios that arise in your programs that also arrive inside the
framework, such as arguments being null, out of range, being invalid, methods not
being implemented, or just not supported, then you should use the same exceptions the
framework uses. The people using your APIs are going to expect that they behave that
way (because that's how everything else behaves), and so will be better able to use
your api from the "get go".
For new scenarios that don't exist in the framework, you should go ahead and invent
your own exception classes. I would say that you should prefer Exception as your base
class unless their is some other base exception that provides services you need.
Generally speaking I don't think something like "ApplicationException" will help you
much. When you start defining your own exceptions there are a few things you should
keep in mind though:
a. The primary purpose of an exception is for human communication. They convey
information about something that happened that shouldn't have. They should provide
enough information to identify the cause of a problem and to figure out how to
resolve it.
b. Internal consistency is extremely important. Making your app behave as universally
as possible under similar circumstances will make you API's users more productive.
As far as there being hard and fast rules about what you should and should not do... I wouldn't worry about that stuff. Instead I would just focus on identifying scenarios, finding the existing exception that fits those scenarios, and then carefully desining your own if an existing one doesn't exist.
You can create and throw pretty much any of them, but you generally shouldn't. As an example, the various argument validation exceptions (ArgumentException, ArgumentNullException, ArgumentOutOfRangeException, etc) are suitable for use in application code, but AccessViolationException isn't. ApplicationException is provided as a suitable base class for any custom exception classes you may require.
See this MSDN article for a list of best practices - it refers to handling exceptions, but also contains good advice on creating them...