I came across this MSDN page that states:
Do not throw Exception, SystemException, NullReferenceException, or IndexOutOfRangeException intentionally from your own source code.
Unfortunately, it does not bother to explain why. I can guess the reasons but I hope that someone more authoritative on the subject might offer their insight.
The first two make some obvious sense, but the latter two seem like ones you would want to employ (and in fact, I have).
Further, are these the only exceptions one should avoid? If there are others, what are they and why should they, too, be avoided?
Exception is the base type for all exceptions, and as such terribly unspecific. You shouldn’t ever throw this exception because it simply does not contain any useful information. Calling code catching for exceptions couldn’t disambiguate the intentionally thrown exception (from your logic) from other system exceptions that are entirely undesired and point out real faults.
The same reason also applies to SystemException. If you look at the list of derived types, you can see a huge number of other exceptions with very different semantics.
NullReferenceException and IndexOutOfRangeException are of a different kind. Now these are very specific exceptions, so throwing them could be fine. However, you still won’t want to throw these, as they usually mean that there are some actual mistakes in your logic. For example the null reference exception means that you are trying to access a member of an object which is null. If that’s a possibility in your code, then you should always explicitly check for null and throw a more useful exception instead (for example ArgumentNullException). Similarly, IndexOutOfRangeExceptions occur when you access an invalid index (on arrays—not lists). You should always make sure that you don’t do that in the first place and check the boundaries of e.g. an array first.
There are a few other exceptions like those two, for example InvalidCastException or DivideByZeroException, which are thrown for specific faults in your code and usually mean that you are doing something wrong or you are not checking for some invalid values first. By throwing them knowingly from your code, you are just making it harder for the calling code to determine whether they were thrown due some fault in the code, or just because you decided to reuse them for something in your implementation.
Of course, there are some exceptions (hah) to these rules. If you are building something that may cause an exception which exactly matches an existing one, then feel free to use that, especially if you are trying to match some built-in behavior. Just make sure you choose a very specific exception type then.
In general though, unless you find a (specific) exception that fills your need, you should always consider creating your own exception types for specific expected exceptions. Especially when you are writing library code, this can be very useful to separate the exception sources.
I suspect the intent with the last 2 is to prevent confusion with inbuilt exceptions that have an expected meaning. However, I'm of the opinion that if you are preserving the exact intent of the exception: it is the correct one to throw. For example, if you are writing a custom collection, it seems entirely reasonable to use IndexOutOfRangeException - clearer and more specific, IMO, than ArgumentOutOfRangeException. And while List<T> might choose the latter, there are at least 41 places (courtesy of reflector) in the BCL (not including arrays) that throw bespoke IndexOutOfRangeException - none of which are "low level" enough to deserve special exemption. So yeah, I think you can justly argue that that guideline is silly. Likewise, NullReferenceException is kinda useful in extension methods - if you want to preserve the semantic that:
obj.SomeMethod(); // this is actually an extension method
throws a NullReferenceException when obj is null.
As you point out, in the article Creating and Throwing Exceptions (C# Programmming Guide) under the topic Things to Avoid When Throwing Exceptions, Microsoft does indeed list System.IndexOutOfRangeException as an exception type that should not be thrown intentionally from your own source code.
In contrast, however, in the article throw (C# Reference), Microsoft seems to violate its own guidelines. Here is a method that Microsoft included in its example:
static int GetNumber(int index)
{
int[] nums = { 300, 600, 900 };
if (index > nums.Length)
{
throw new IndexOutOfRangeException();
}
return nums[index];
}
So, Microsoft itself isn't being consistent as it demonstrates the throwing of IndexOutOfRangeException in its documentation for throw!
This leads me to believe that at least for the case of IndexOutOfRangeException, there may be occasions where that exception type can be thrown by the programmer and be considered an acceptable practice.
When I read your question, I asked myself under what conditions one would want to throw the exception types NullReferenceException, InvalidCastException or ArgumentOutOfRangeException.
In my opinion, when encountering one of those exception types, I (the developer) feel concerned by the warning in the sense that the compiler is talking to me. So, allowing you (the developer) to throw such exception types is equivalent to (the compiler) selling the responsibility. For instance, this suggests the compiler should now allow the developer to decide whether an object is null. But making such a determination should really be the job of the compiler.
PS: Since 2003 I have been developing my own exceptions so I can throw them as I wish. I think it is considered a best practice to do so.
Putting the discussion about NullReferenceException and IndexOutOfBoundsException aside:
What about catching and throwing System.Exception. I've thrown this type of exception in my code a lot and I was never screwed by it. Similarly, very often I catch the unspecific Exception type, and it also worked pretty well for me. So, why is that?
Usually users argue, that they should be able to distinguish error causes. From my experience, there are just a very few situations where you would want to handle different exception types differently. For those cases, where you expect users to handle errors programmatically, you should throw a more specific exception type. For other cases, I'm not convinced by the general best practice guideline.
So, regarding throwing Exception I don't see a reason to prohibit this in all cases.
EDIT: also from the MSDN page:
Exceptions should not be used to change the flow of a program as part of ordinary execution. Exceptions should only be used to report and handle error conditions.
Overdoing catch clauses with individual logic for different exception types are not best practice, either.
Related
nothing more frustrating than to see your code crash in the debugger on a method which exceptionned and you didn't try/catch it.
Is there an easy way to scan through your sources and tag all functions which can potentially throw exceptions?
Does the build in visual assist have some hidden option to colour these functions in a specific color?
thanks
R
All code but the most trivial could throw exceptions (out of memory, at the very least). You're probably better off writing your code defensively, with at least a global try/catch rather than trying to micromanage which sections of code will or won't throw exceptions.
No, there is no way to automatically do this nor is there a good way to get a list of all possible exceptions thrown by a method. Here are a few reasons why
Consider implicitly thrown exceptions such as StackOverflowException can be thrown at any time from any method. You must assume that any method in the CLR can throw these types of exceptions
Reflection and / or delegates can hide the actual code being called in a particular method so you cannot inspect all possible code paths of a method.
This would require inspecting IL vs. metadata.
In .Net there is no requirement to document exceptions that are explicitly thrown by an API
I think redgate have some a tool for this "Exception Hunter"
They charge for it after a trial.
http://www.red-gate.com/products/Exception_Hunter/index.htm
As others have said, I'm not sure if you'll find a foolproof way of doing this in C# since doesn't support checked exceptions.
As a bit of an aside, this reminded me of an interview with Anders Hejlsberg discussing "The trouble with Checked Exceptions". I'm not trying to flame checked exceptions, but suggesting that you read Ander's rationale behind C#'s exception design and the suggested way for handling exceptions: centralized exception handling.
I think the resharper gives you hints on exceptions. But due to the reason that C# doesn't support checked exceptions, there is way to determine the exceptions. Maybe code analysis tools like NDepend support this.
Everything can throw an exception. Check MSDN for a list of exceptions that can be thrown by a method.
All non-empty methods can throw exceptions in one form or another. If you're concerned about exceptions you have personally generated, you can display them from intellisense in the same way framework methods do via XML documentation, like this:
/// <summary>
/// I seem to have written a method to do a thing.
/// </summary>
/// <exception cref="System.Exception">An unfortunate failure.</exception>
public void DoSomething()
{
/* ... */
}
Any code could potentially cause an exception it is your job to try and anticipate this!
There are a number of third party tools that may assist with finding some common errors e.g fxcop and tools such as refactor can make suggestions.
There is some work been done at the moment that can assist you with finding potential exceptions. Take a look into PEX which can help generate tests for your functions: research.microsoft.com/en-us/projects/Pex/ (link seems to be down at time of posting)
Another exciting area is code contracts (coming in .net 4/available as spec#). Code contracts allow you to write statements that specify conditions that must be met. These can be prior to and after your function being called and you can also declare invariants. A condition might be something as simple as value != null. These conditions are then analyzed at compile and runtime to check no code paths violate them.
As the others have said, you should assume that every single line of code can throw an exception, unless you've proven that it cannot. The better question is, "what do you plan to do about that?"
In general, you should not be catching any exceptions at all.
Of course, everything else is an exception to that rule. It makes sense to catch an exception in order to log it (if your environment doesn't do that for you, as ASP.NET does). It makes sense to catch an exception in order to replace it with another exception that provides more detail about the context:
public int GetConfiguredInteger(string name) {
string s = null;
try {
s = GetStringFromConfigFile(name);
}
catch (IOException ex) {
throw new Exception(String.Format(
"Error in configuration file foo.config when processing {0}", name),
ex);
}
return int.Parse(s);
}
The caller couldn't have known that the IOException was caused by a config file if you hadn't told them. Note also how I ignored all exceptions not related to the file I/O. In particular, note that the int.Parse is not even inside of the try/catch block.
There are a small number of other such exceptions, but the basic idea of catching exceptions is: don't do it unless it would be worse if you didn't.
There is a reflector add in Exception Finder which will show what exceptions could be thrown by a method. I haven't used it but saw an example of it at a .Net users group meeting.
There is a tool out there that can do this. You could download the trial and see if you like it. I don't really think it would be that necessary, but if you are working for a company and they'll pay for it you might want to look into it. Like has been said before there are just too many possible exceptions that be raised. Check out Excpetion Hunter
Exception Hunter mentioned by a few people is a good tool to help with this. I do not know whether it has a tie-in with the <exception> XML-Doc comment so that you can enforce documentation of exceptions thrown by code.
I find it much more frustrating to break inside an outer catch block and dig my way down to the actual point where the exception happend.
Most of the time if an exception was thrown and I didn't expect it I found a bug and it's easier to solve it if it wasn't obfuscated by some doing-nothing exception handling.
EDIT:
Since your examples is actually a good one I'm still not convinced that such a tool would help you. There would be so many possible exceptions that literally every line of code could throw that you would have a hard time to find the "interesting" ones.
It's often said that you shouldn't use exceptions for regular error handling because of bad performance. My guess is that that bad performance is caused by having to instantiate a new exception object, generate a stack trace, etc. So why not have lightweight exceptions? Code like this is logically sound:
string ageDescription = "Five years old";
try {
int age = int.Parse(ageDescription);
}
catch (Exception) {
// Couldn't parse age; handle parse failure
}
And yet we're recommended to use TryParse instead to avoid the overhead of the exception. But if the exception were just a static object that got initialized when the thread started, all the code throwing the exception would need to do is set an error code number and maybe an error string. No stack trace, no new object instantiation. It would be a "lightweight exception", and so the overhead for using exceptions would be greatly reduced. Why don't we have such lightweight exceptions?
The exception object instantiation is the smallest problem in the whole case. The real performance killer is that the control flow must stop executing your program and has to look up the call stack for possible handlers (catch blocks) that can catch the thrown exception, then it has to execute the correct ones (and their finally blocks), rethrow exceptions when told so and then continue executing the program on the right place, i.e. after the last handler. Your idea of "lightweight" exceptions would change nothing of this, it would even slow down creation of threads, because it would have to create and store the exception object, and would prevent exception filtering by type, which is now possible.
By using TryParse, you avoid all this by a simple conditional clause, also you actually write less code and it is much easier to read and reason about.
Exceptions are for exceptional cases and in such scenarios, they provide lots of useful information for logs/debugger.
The performance hit isn't just because you're creating a new Exception object. A lot of it has to do with the conditional unwinding of the stack that needs to be done when an exception occurs.
For example, think about the work that would have to be done when you have exception handlers that catch different kinds of exceptions. At each point in the stack, as it's unwound from callee to caller, the language must do a type check to see not only if the exception can be handled, but what the most appropriate handler is. That's a significant amount of overhead in its own right.
If you really want to be lightweight, you should return a result from your functions -- that's what Int32.TryParse() does. No stack unwinding, no type checking, just a simple condition which can easily be optimized for.
EDIT: One somewhat interesting thing to note is that C# was created after Java. Java has a couple of interesting constructs which cause exception handling to be more complicated than what we see in C#, namely checked exceptions and the throws keyword. Kind of interesting reads. I'm (personally) glad that C# didn't include this "feature". My guess is that they bifurcated their exception handlers to boost performance. In the real world, as I understand it, a LOT of developers just end up specifying throws exception in their function declarations.
You should use int.TryParse in your case. And it is faster and more readable to test some conditions then to throw and catch exception. Use exceptions for exceptional situations not for regular validation.
The problem with exceptions isn't just generating the exception itself, that's honestly not even the most time consuming part. When you throw an exception (after it has been created) it needs to unwind the stack going through each scope level, determining if that scope is a try/catch block that would catch this exception, update the exception to indicate it went through that section of the stack, and then tearing down that section of the stack. And then of course there are all of the finally blocks that may need to be executed. Making the Exception itself store less information wouldn't really simplify any of that.
Because the utility offered by the "heavyweight" exceptions is exceptionally (ha ha) useful. I can't tell you how often I've wanted the ability to dump something like a stack trace in C land without having to ask people to yank out a debugger.
Generating things like the stack trace after the fact (i.e. after the exception has been caught on demand) are infeasible because once the exception has been caught, the stack has been unwound -- the information is gone. You want information about the point of failure; so the data must be collected at the point of failure.
As for the "new object instantiation" -- that is so cheap in comparison to other expensive exception features (unwinding the stack, stack trace, multiple function exit points, etc.) that it isn't worth worrying about.
You're not recommended to use TryParse instead of Parse because of performance. If there's any chance a parse can fail (because it's user generated input for example) then the failure to parse is not exceptional, it's to be expected. As the name implies, exceptions are for exceptional circumstances. For stuff that should have been caught earlier, but wasn't, so unexpected that you can't really continue.
If a function expects an object but instead null is passed in, then it's up to the designer of the method what the right thing to do is in this case. If the parameter is an optional override for a default, the program ca continue and use the default or ignore the parameter. But otherwise, the program should simply throw a ArgumentNullException.
Performance shouldn't be a consideration at all when deciding to use exceptions or not. It's a matter of intent and purpose. They're not even that slow, sure they're many times slower than adding two integers, but I can still throw 50,000 exceptions per second on my aging Core 2 Duo. If the use of exceptions ever becomes a bottleneck, you're not using them in the right way.
I've read that throwing exceptions is an expensive operation. However, doesn't creating your own exceptions make your code more expressive and readable?
Some of my coworkers suggest that you should just use System.Exception and insert your custom text into the message instead of creating a new custom exception.
I'm interested in other opinions. Appreciate any suggestions.
Do not throw System.Exception. Ever.
The problem with it resides in the calling code. It is a bad practice to catch the general Exception object for many reasons. If you throw an instance of the Exception base class, then calling code has no choice but to catch Exception if they want to handle it. This forces the calling code to use a bad practice.
Also, the calling code has no reliable means of distinguishing what the exception was, if all it gets is Exception.
It is typically best to use one of the pre-defined exceptions if any are applicable (ArgumentException, InvalidOperationException, etc.). If none correctly describe the situation, then a custom exception class is a perfectly good way to go.
It's the overhead of throwing an exception itself (creating the object, walking the stack, etc.) that's costly. Making your own exception class adds almost no overhead, so if you're going to throw an exception, don't make it new Exception("message")!
Exceptions aren't meant to be read by people (though their messages and stack traces are read by people), they're meant to be read by code. If there's something your code can do in response to a custom exception, by all means go for it. But the exception is just destined to be logged, there's no point to making a custom one.
The overhead of custom exceptions is that they're another thing to maintain and test. If an existing exception is suitable, use that instead. (E.g., ArgumentNullException instead of ZipCodeNullException.)
If there's any reason for your exception to be caught and handled differently from standard Exceptions, then you should create your own class.
If there's any reason for your exception to take different arguments (e.g. to produce a specially-formatted message based on a set of arguments that you're often likely to have), then you should create your own class.
In any other case, you're safe just using Exception. Generally speaking, it doesn't really cost any more to instantiate or throw a custom exception than a standard one, at least not compared with the expense of throwing an exception in the first place. Exceptions, by definition, should be exceptional, and therefore performance during the throwing of an exception is a non-issue. The point is to have all the information you need when the time comes to look at why that exception was thrown.
You should never throw a System.Exception, because then the only way to catch is is by catch(System.Exception). It's very bad practice to catch a blanket exception like that. You should catch specific exceptions, which give you a way to properly handle it without crashing the software. By generating custom exceptions, you give yourself a way to potentially recognize and recover from them.
For example, if your code means to open a file, and you get an unknown exception, how do you recover from it? However, if you catch a specific File Not Found exception, that is much easier to recover from. You can tell the user definitively that the file doesn't exist.
I don't see a reason to believe that custom exceptions are any more expensive than the built-in ones.
"Expensive" is a relative term and - as the name already suggests - an exception should be an exception, so it will probably not affect the performance of your code. The cost of throwing an exception is - as far as I know - independent of the type of the exception, so you should not restrict yourself to System.Exception.
But most important: http://c2.com/cgi/wiki?PrematureOptimization
I prefer to use the most appropriate built in exception, and if that doesn't already exist, derive my own from System.ApplicationException.
I wouldn't recommend throwing System.Exception with a custom message.
Your coworker is talking nonsense. Throwing an exception is the same cost regardless of the class.
And to be honest, all this talk of "expensive" exceptions - yes they are more expensive than a null check or some such, so don't ever use them as a replacement for some sanity check, but they should be encouraged where they make sense (like IOException for example, that's an excellent use case for them - problems with I/O are an exceptional case and they usually must be handled outside of normal program flow).
Are there any cases when it's a good idea to throw errors that can be avoided?
I'm thinking specifically of the DivideByZeroException and ArgumentNullException
For example:
double numerator = 10;
double denominator = getDenominator();
if( denominator == 0 ){
throw new DivideByZeroException("You can't divide by Zero!");
}
Are there any reasons for throwing an error like this?
NOTE: I'm not talking about catching these errors, but specifically in knowing if there are ever good reasons for throwing them.
JUST TO REITERATE:
I KNOW that in the example I gave you'd probably be better off handling the error. Perhaps the question should be rephrased. Are there any reasons to throw one of these errors instead of handling it at this location.
Let's say you write a library to work with really big integers that don't fit into Int64, then you might want to throw DivideByZeroException for the division algorithm you write.
The .NET runtime is already very good at throwing these exceptions. They are also highly descriptive of what is wrong, you can't add any good commentary to the exception message. "You can't divide by zero" adds no value.
However, you can avoid many of these exceptions by screening the values passed by the client code. You'll want ArgumentNullException with the name of argument if the client code passed a null, ArgumentException when it passed something that is liable to trip DivideByZero.
There is absolutely a reason to do this, and as with most exception throwing questions, you have to think about you as a developer working in a team. What you're writing may be part of another system, or it may be a library or component.
If you write a maths library , and have a function called Divide(int a, int b) that divides them, if someone else wants to use your method and passes in zero, you'll want to throw an exception so they, as a developer, know they've screwed up.
If you don't throw an exception, you introduce bugs into your code. If I used your divide method, and put the values 10 and 0 in, which produces 10/0 and thus an exception, the only correct answer is error. If you decide to change the values so no error occurs, or return 0, that is not what I am expecting - I assume my division worked perfectly, and never notice a problem. I might well take that 0 and go off and use it in other calculations, unaware that it's the wrong answer, because 10/0 is not 0.
You should only use an Exception to handle Exceptional cases.
In this case, it looks like a zero would be invalid user input. You should check for invalid user input and handle it accordingly BEFORE you get to the point that an Exception would be approriate.
As long as you properly handle input, there should be no reason for a DivideByZeroException to happen. If you receive a DivideByZeroException even after validating input...then you know you have a real problem (in which case, the Exception is appropriate).
If you're talking about code that is directly interacting with the UI, then no. I can't think of any reason why you'd want to.
However, if you're building a class/object used by other devlopers and they've passed in data that is clearly stupid then throw the appropriate error during your validation.
If you're writing a BigInteger library, then you absolutely should throw an appropriate DivideByZero exception. If you're writing a shopping-cart library, then...eh, probably not.
I can't, at the moment, think of a good reason to throw a NullReferenceException. If you're create an API with documentation that says "The first parameter to HummingBirdFeeder.OpenSugarWaterDispenser(Dispenser dispenser, int flowRate) is the sugar-water dispenser that you wish to open." And if somebody then comes along and passes a null value to this method, then you should definitely throw an ArgumentNullException.
Letting a NullReferenceException out of your API would just be lazyness, though, because that's wrong and it leaks some of your internals.
EDITED TO ADD:
Now that you changed the question to refer to an ArgumentNullException then the answer is easy: yes, you should definitely throw that kind of exception under these circumstances:
You are writing a public method.
Getting a null value for the argument is in some way inappropriate (i.e., the method makes no sense without that particular argument).
The documentation for the method indicates that null values are not allowed.
In that case, the very first thing your method should do is check for a null value and throw an exception if the condition is violated.
If you are writing a private or internal method, then in most cases you would not need to validate the parameters at runtime in the release build. You can make sure that your own code calls your own code correctly. One thing that helps to create that assurance is to validate the parameters in the debug build by adding assersions:
Debug.Assert(dispenser != null);
This way you can verify that the code is acting correctly and catch any errors earlier without slowing down the released code with a bunch of useless, redundant checks.
In your own code, I doubt there would be much use. However, if you are writing a library that will be consumed by others then you should use exceptions as the means of communicating errors back to the code consuming your library.
"In the Framework, exceptions are used
for both hard errors and logical
errors. At first, it can be difficult
to embrace exception handling as the
means of reporting all functional
failures. However, it is important to
design all public methods of a
framework to report method-failures by
throwing an exception."
Krzysztof Cwalina, Designing Reusable Frameworks
Slightly misleading title here, it is not about throwing the (special) DivideByZeroException but rather the question:
Should I use exceptions while validating user input?
This has probably been asked before. My take: No, just use a flow that lets you handle this with error codes or booleans.
However, when validating 'data' in deeper layers of an app, throwing an exception is usually the right thing to do.
If you were writing a numerical class of some form and can have expected the code calling your class to have performed the validation then I can see it might useful to throw DivisionByZeroException but in almost any other case it would better to check before the operation and throw and ArgumentException or ArgumentOutOfRange exception as appropriate.
NullReferenceException is one of the reserved exceptions that the framework uses that you should never throw through a public API, along with IndexOutOfRange, AccessViolationException and OutOfMemoryException. See the Framework Design Guidelines book or the Code Analysis warning explanation
None that I can think of. I would just program against it. Exceptions can be expensive, so if you can defensively program against it, do that instead of throwing an exception.
At least that's what my senior dev told me when I tried catching a DivideByZeroException many moons ago.
Its a good practice to make these checks at top of the function before you start processing data. Rather then throwing them (or any other method throws these exceptions) in the middle of a method.
In theory (and practice too), identifying and avoiding/eliminating erroneous cases is better than treating them as exceptions. However, it's not always possible to test every case or path through your code - it's also not possible in every case to control your inputs.
A tenet of good design is to have your program recognize and gracefully handle exceptional situations. Furthermore, it's a good idea to provide your users (and ultimately yourself) enough information to diagnose errors - particularly those that can occur after your code is deployed. Therefore, it does sometimes make sense to throw exceptions such as the kind illustrate if it will make your application code more robust and easier to diagnose.
Never (the user will never send 0 as the denominator) and always (the user will always provide appropriate argument values) are dangerous ideas to include in your code. A very small percentage of us program alone, on code that will never be modified or called by another developer. So, we need to write defensive code. In the case of division by zero, I should not be deciding what the appropriate result should be, that falls back on the caller. Throwing the exception seems like a reasonable way to hand the issue back. While there is expense involved, any infrastructure I add to my code to avoid throwing the exception also adds expense.
Consider that for doubles, a division by zero will actually result in a value: double.Infinity, double.NegativeInfinity or double.NaN, depending upon whether the numerator is positive, negative or zero, respectively.
It may be that these values are already suitable for your case, if not you will probably want to validate the input, and act accordingly, before you perform the division.
If you are writing an API (such as on a library) and want to provide a contract that disallows a division by zero (say it exposes method that performs some kind of division) then you may want to throw this exception then. Typically though, I would reserve this type of exception as an indicator of a programmatic error.
If you are relying on a framework to do the work (.NET or otherwise), then you should let the framework throw the exception.
This will make it easier for consumers of your methods to handle exceptions that are thrown in a standard way.
In the case for dividing by zero, you are just re-implementing the same logic to throw an exception as in the framework.
Throwing an exception is an expensive thing to do from a resource point of view. You have already prevented an exception from occurring so why throw one? If you have to tell the user, use some messaging mechanism. If you need to know about it yourself, log it.
nothing more frustrating than to see your code crash in the debugger on a method which exceptionned and you didn't try/catch it.
Is there an easy way to scan through your sources and tag all functions which can potentially throw exceptions?
Does the build in visual assist have some hidden option to colour these functions in a specific color?
thanks
R
All code but the most trivial could throw exceptions (out of memory, at the very least). You're probably better off writing your code defensively, with at least a global try/catch rather than trying to micromanage which sections of code will or won't throw exceptions.
No, there is no way to automatically do this nor is there a good way to get a list of all possible exceptions thrown by a method. Here are a few reasons why
Consider implicitly thrown exceptions such as StackOverflowException can be thrown at any time from any method. You must assume that any method in the CLR can throw these types of exceptions
Reflection and / or delegates can hide the actual code being called in a particular method so you cannot inspect all possible code paths of a method.
This would require inspecting IL vs. metadata.
In .Net there is no requirement to document exceptions that are explicitly thrown by an API
I think redgate have some a tool for this "Exception Hunter"
They charge for it after a trial.
http://www.red-gate.com/products/Exception_Hunter/index.htm
As others have said, I'm not sure if you'll find a foolproof way of doing this in C# since doesn't support checked exceptions.
As a bit of an aside, this reminded me of an interview with Anders Hejlsberg discussing "The trouble with Checked Exceptions". I'm not trying to flame checked exceptions, but suggesting that you read Ander's rationale behind C#'s exception design and the suggested way for handling exceptions: centralized exception handling.
I think the resharper gives you hints on exceptions. But due to the reason that C# doesn't support checked exceptions, there is way to determine the exceptions. Maybe code analysis tools like NDepend support this.
Everything can throw an exception. Check MSDN for a list of exceptions that can be thrown by a method.
All non-empty methods can throw exceptions in one form or another. If you're concerned about exceptions you have personally generated, you can display them from intellisense in the same way framework methods do via XML documentation, like this:
/// <summary>
/// I seem to have written a method to do a thing.
/// </summary>
/// <exception cref="System.Exception">An unfortunate failure.</exception>
public void DoSomething()
{
/* ... */
}
Any code could potentially cause an exception it is your job to try and anticipate this!
There are a number of third party tools that may assist with finding some common errors e.g fxcop and tools such as refactor can make suggestions.
There is some work been done at the moment that can assist you with finding potential exceptions. Take a look into PEX which can help generate tests for your functions: research.microsoft.com/en-us/projects/Pex/ (link seems to be down at time of posting)
Another exciting area is code contracts (coming in .net 4/available as spec#). Code contracts allow you to write statements that specify conditions that must be met. These can be prior to and after your function being called and you can also declare invariants. A condition might be something as simple as value != null. These conditions are then analyzed at compile and runtime to check no code paths violate them.
As the others have said, you should assume that every single line of code can throw an exception, unless you've proven that it cannot. The better question is, "what do you plan to do about that?"
In general, you should not be catching any exceptions at all.
Of course, everything else is an exception to that rule. It makes sense to catch an exception in order to log it (if your environment doesn't do that for you, as ASP.NET does). It makes sense to catch an exception in order to replace it with another exception that provides more detail about the context:
public int GetConfiguredInteger(string name) {
string s = null;
try {
s = GetStringFromConfigFile(name);
}
catch (IOException ex) {
throw new Exception(String.Format(
"Error in configuration file foo.config when processing {0}", name),
ex);
}
return int.Parse(s);
}
The caller couldn't have known that the IOException was caused by a config file if you hadn't told them. Note also how I ignored all exceptions not related to the file I/O. In particular, note that the int.Parse is not even inside of the try/catch block.
There are a small number of other such exceptions, but the basic idea of catching exceptions is: don't do it unless it would be worse if you didn't.
There is a reflector add in Exception Finder which will show what exceptions could be thrown by a method. I haven't used it but saw an example of it at a .Net users group meeting.
There is a tool out there that can do this. You could download the trial and see if you like it. I don't really think it would be that necessary, but if you are working for a company and they'll pay for it you might want to look into it. Like has been said before there are just too many possible exceptions that be raised. Check out Excpetion Hunter
Exception Hunter mentioned by a few people is a good tool to help with this. I do not know whether it has a tie-in with the <exception> XML-Doc comment so that you can enforce documentation of exceptions thrown by code.
I find it much more frustrating to break inside an outer catch block and dig my way down to the actual point where the exception happend.
Most of the time if an exception was thrown and I didn't expect it I found a bug and it's easier to solve it if it wasn't obfuscated by some doing-nothing exception handling.
EDIT:
Since your examples is actually a good one I'm still not convinced that such a tool would help you. There would be so many possible exceptions that literally every line of code could throw that you would have a hard time to find the "interesting" ones.