Need help to get out of the exception jungle - c#

I've googled for quiet a time now and I still don't know which exception to use in which scenario. I've read that it's bad practice to raise SystemExceptions in your own code, because those exception should better get raised by the CLR.
But well, now I want to know what Exeption I should raise in different scenarios. Let's say I have a method which gets invoked with an enum as Parameter. That isn't a very good example - it just came off the top of my head.
public enum CommandAppearance
{
Button,
Menu,
NotSpecified
}
//...
public void PlaceButtons(CommandAppearance commandAppearance)
{
switch(commandAppearance)
{
case CommandAppearance.Button:
// do the placing
case CommandAppearance.Menu:
// do the placing
case CommandAppearance.NotSpecified:
throw ArgumentOutOfRangeException("The button must have a defined appearance!")
}
}
What would it be here? Is there some kind of site, where I can get an overview? Are there any patterns which tell you what kind of exception to raise? I'd just need some tips at this topic, because I'm pretty unconfident with this.
I think raising just new Exception()s isn't good practice, either, is it?

I'm sure ArgumentOutOfRangeException is the best buid-in exception for this. Also ReSharper suggests it.
If you need some another.. then the single way is to create the new special exception CommandAppearanceIsNotSpecifiedException.

For your example scenario, I would suggest either:
ArgumentOutOfRangeException if the method supports ALL values in the enum and an invalid value is passed.
NotSupportedException if the method supports a subset of the values in the enum.
Generally speaking, you want to make use of the exception types See this list of exceptions in the .net framework where possible and it makes sense, otherwise you want to introduce your own. This may involve adding a common application exception for your application and adding more specific ones which inherit from it.
e.g.
public class MyAppException : Exception
{
// This would be used if none of the .net exceptions are appropriate and it is a
// generic application error which can't be handled differently to any other
// application error.
}
public class CustomerStatusInvalidException : MyAppException
{
// This would be thrown if the customer status is invalid, it allows the calling
// code to catch this exception specifically and handle it differently to other
// exceptions, alternatively it would also be caught by (catch MyAppException) if
// there is no (catch CustomerStatusInvalidException).
}

Related

Is it bad to skip exception constructor overloads if you're not going to use them?

According to MSDN's Best Practices for Exceptions, you should create three constructors for your custom exceptions, namely Exception(), Exception(String), and Exception(String, Exception):
In C# and C++, use at least the three common constructors when creating your own exception classes: the default constructor, a constructor that takes a string message, and a constructor that takes a string message and an inner exception. For an example, see How to: Create User-Defined Exceptions.
Such a blanket statement strikes me as a bit odd considering that you can use an exception purely internally in your software, in one specific way, and never intend for it to be caught or thrown by external code.
For example, I'm creating software for converting between two file formats. Before conversion, I check the input file for non-unique IDs (it shouldn't have and usually doesn't - this is exceptional behaviour), and if found, raise my own DuplicateIdException:
public class DuplicateIdException : Exception
{
public DuplicateIdException(List<string> ids)
{
Duplicates = ids;
}
public List<string> Duplicates { get; }
}
This exception is caught further up the stack, the duplicate IDs logged, and the conversion process aborted. Since this is the only usage scenario for this exception, I will only ever use that one constructor. I don't even need the ubiquitous message parameter for anything (though if I did, I'd just add it to this constructor.)
I just don't see the reason to have unused code that allows unintended uses by future maintainers (including myself, having forgot all about this a year down the road).
In cases such as these, is it bad practice to omit the other constructors? If so, why? Are there any pitfalls to be aware of?

Exception Class Visibility?

Been using C# for about five years and only now did it strike me about the class visibility of custom exceptions. It's perfectly legal to write internal or even private nested exceptions like so:
internal class WhyDoThis : Exception { }
public class Foo { private class WhyWhyWhy : Exception { } }
So when you go about throwing these exceptions in your DLLs, only the (minority of) people doing decent (non pokemon) exception handling get their apps crashed.
So my question is, what's the purpose of such a pattern? Or why is this even legal?
A simplistic answer would be: it's just as legal as any bad code can be.
I really can't think of anything else to say here that won't go beyond the scope of that question. That's just how it is. Anyone, at any time, can write code that even though can compile is just plain and simply awful.
EDIT:
I actually can think of one scenario where internal exceptions can have some use: for testing and asserting frameworks, like Code Contracts. But that's a very marginal case.
One purpose would be for an exception that is used internally to an assembly (or even privately to a class), but where the exception never escapes the assembly (or the class). In that case, you wouldn't want it to become visible outside the assembly (or class).
In this case, it would obviously be a bug if the exception were to escape the assembly (or class).
There nothing wrong from inheritance/visibility point of view to have internal/private exceptions. It is exactly the same as providing private class to implement public interface - whoever uses that object outside will not be able (short of reflection) to obtain details that are not exposed via public interface/base class.
So in exception case external callers will only be able to catch public base exception even if you fire very specific private exception. You may do that to provide custom ToString for example.
Note that private/internal exceptions are probably bad idea as whole reason of throwing specific exception is to let someone to catch specific one.
Also check out Designing Custom Exceptions to make sure your exception classes are useful in all cases (like cross-domain exceptions require serialization).

Exiting a Class From C# Using a Catch

I'm looking for the best method of handling errors in a c# winforms class that I have. The gist of the application is that it has a data analyzer that analyzes the data for statistics and other such stuff. However, I'm looking for the proper way of handling an ABORT.
For example, I have the class called Analyzer
namespace PHOEBE
{
public class Analyzer
{
public Analyzer(){
DoAnalysis();
DoFurtherAnalysis();
}
public class DoAnalysis(){
try{
Convert.ToInt32("someNumber...."); //obviously fails..
}
catch{
//ERROR OCCURRED, ABORT ALL ANALYSIS
return;
}
}
}
Obviously, when DoAnalysis() is called, there will be an error that occurs. The catch block will catch the exception. However, when this catch occurs, it will return to the constructor and run DoFurtherAnalysis(). This is a problem.
I know that you could do return values from each method where each value indicates a certain outcome (ie. 1 = success, 0 = fail). However, a lot of the methods I call, use return values already. I could also use a boolean that gets flagged when an error occurs and check that value before calling the next method from the constructor, but checking this value each time is annoying and repetitive.
I was really hoping for some sort of like "abort mechanism" that I could use. Is there any other ways of working around this? Any interesting work-arounds for this?
Assume this class is being called from a form.
Just let the exception propagate up - you should only catch the exception if you can actually handle it. Exceptions are the "abort mechanism" in .NET. You're currently swallowing the signal that everything's gone wrong, and returning as if all were well.
Generally I find catching exceptions to be pretty rare - usually it's either at the top level (to stop a whole server from going down just because of one request) or in order to transform an exception of one kind into another in order to maintain appropriate abstractions.
I was really hoping for some sort of like "abort mechanism" that I
could use. Is there any other ways of working around this? Any
interesting work-arounds for this?
Yes, there is. It is called exception handling.
Let's rewrite your code:
namespace PHOEBE
{
public class Analyzer
{
public Analyzer()
{
try
{
DoAnalysis();
DoFurtherAnalysis();
}
catch
{
//ERROR OCCURRED, ABORT ALL ANALYSIS
return;
}
}
public class DoAnalysis()
{
Convert.ToInt32("someNumber...."); //obviously fails..
}
}
Now, the constructor will abort and not run the second method since the exception will "bubble through" and be catched where you want it.
On an unrelated note: Please try to catch as specific exceptions as possible, in this case a FormatException
You are subverting the existing "abort" mechanism by catching an exception that you are not doing anything about and swallowing it.
You should not use a try{}catch{} block in this case and let the exception bubble up and cause the application to abort.
The easiest work-around is don't catch the exception. If that were to happen, it'd go straight past the DoFurtherAnalysis() function and out to the original caller.
Don't see anything anoying in returning and checking bool return value from the function. It's much much better solution then having some tricky internal state management, that you for sure will messed up after a couple of months when you return to your code.
Make code sumple and streghtforward. It's not anoying, it's good.
In your specific case if you want just abort everything, just do not catch exception it will abort your program.
use a try...catch in the constructor?
Well, you've got several issues mixed up here. First, it looks like you do possibly-very expensive processing from your constructor. If that processing can throw, you really don't want to call it from your constructor becuase you don't even have the option of returning an error code.
Second, (and you'll read in many threads here,) how you handlee errors really depends on the application and expectation of your users. Some errors could be corrected by changes to inputs. Others might happen in the middle of the night if analysis takes a long time and you might want to continue with another analysis, logging this error.
So I think we're really going to punt back to you for more information about the above.
You could just move DoFurtherAnalysis(); into the the try block
And I would do this entire process somewhere other than the constructor.
Only thing I ever do in the constructor is initialize properties.

Which Exception Should I Throw to Signal an Internal Error in my Program?

Which exception should I use when the program reaches a logic state that I "know" won't happen, and if it does, something is terribly bad?
For example:
int SomeFunction(int arg) {
SomeEnum x = Whatever(arg, somePrivateMember);
switch (x) {
case SomeEnum.Value1:
return SomeFunction1();
case SomeEnum.Value1:
return SomeFunction2();
default:
throw new WhatTypeToThrow();
}
}
Clearly, ArgumentException is a long-shot here since the invalid value for x could have come from a bug in Whatever(), or an invalid combination of any arguments and/or the current instance state.
I'm looking for something such as an InvalidProgramStateException, InternalErrorException or similar.
Of course I could define my own, but I wonder if there is a suitable exception in the framework.
Edit: Removed the simple sample code to reduce amount of ArgumentException answers.
What about InvalidOperationException?
Why not the InvalidEnumArgumentException? It looks like it was designed specifically for this use-case.
Don't throw any specific exception type in the code you're looking at. Call Trace.Assert, or in this case even Trace.Fail to get a similar effect to Debug.Assert, except enabled even in release builds (assuming the settings aren't changed).
If the default trace listener, the one that offers a UI that offers to kill the whole program or launch a debugger, isn't appropriate for your needs, set up a custom trace listener in Trace.Listeners that causes a private exception type to be thrown whenever Trace.Fail is called (including when a Trace.Assert fails).
The exception type should be a private exception type because otherwise, callers may be tempted to try catching whatever exception type you're going to throw. For this particular exception type, you will want to make it as clear as possible that a future version of the method will no longer throw this particular exception. You don't want to be forced to throw a TraceFailedException or whatever you call it from now until eternity to preserve backwards compatibility.
Another answer mentioned Code Contracts already as an alternative. It is, in a similar way: you can call Contract.Assert(false). This takes the same approach of making it customisable what happens if an assertion fails, but in this case, the default behaviour is to throw an exception, again of a type that is not externally accessible. To make the most of Code Contracts, however, you should be using the static rewriter, which has both pros and cons that I will not get into here. If for you the pros outweigh the cons, then by all means use it. If you prefer to avoid the static rewriter though, then I'd recommend avoiding the Contract class entirely, since it is not at all obvious which methods do and don't work.
I think ArgumentOutOfRangeException is valid here and it's what I use. It's the argument to the switch statement that is not handled as it's out of the range of handled values. I tend to code it like this, where the message tells it like it is:
switch (test)
{
case SomeEnum.Woo:
break;
case SomeEnum.Yay:
break;
default:
{
string msg = string.Format("Value '{0}' for enum '{1}' is not handled.",
test, test.GetType().Name);
throw new ArgumentOutOfRangeException(msg);
}
}
Obviously the message is to your own tastes, but the basics are in that one. Adding the value of the enum to the message is useful not only to give detail concerning what known enum member was not handled, but also when there is an invalid enum i.e. the old "(666)SomeEnum" issue.
Value 'OhNoes' for enum 'SomeEnum' is not handled.
vs
Value '666' for enum 'SomeEnum' is not handled.
Here are suggestions that I've been given:
ArgumentException: something is wrong with the value
ArgumentNullException: the argument is null while this is not allowed
ArgumentOutOfRangeException: the argument has a value outside of the valid range
Alternatively, derive your own exception class from ArgumentException.
An input is invalid if it is not valid at any time. While an input is unexpected if it is not valid for the current state of the system (for which InvalidOperationException is a reasonable choice in some situations).
See similar question and answer that I was given.
You should consider using Code Contracts to not only throw exceptions in this case, but document what the failed assumption is, perhaps with a friendly message to the programmer. If you were lucky, the function you called (Whatever) would have a Contract.Ensures which would catch this error before you got your hands on it.
program reaches a logic state that I "know" won't happen, and if it does, something is terribly bad.
In this case, I would throw an ApplicationException, log what you can, and exit the app. If things are that screwed up, you certainly shouldn't try to recover and/or continue.

Best practices: throwing exceptions from properties

When is it appropriate to throw an exception from within a property getter or setter? When is it not appropriate? Why? Links to external documents on the subject would be helpful... Google turned up surprisingly little.
Microsoft has its recommendations on how to design properties at http://msdn.microsoft.com/en-us/library/ms229006.aspx
Essentially, they recommend that property getters be lightweight accessors that are always safe to call. They recommend redesigning getters to be methods if exceptions are something you need to throw. For setters they indicate that exceptions are an appropriate and acceptable error handling strategy.
For indexers, Microsoft indicates that it is acceptable for both getters and setters to throw exceptions. And in fact, many indexers in the .NET library do this. The most common exception being ArgumentOutOfRangeException.
There are some pretty good reasons why you don't want to throw exceptions in property getters:
Because properties "appear" to be fields, it is not always apparent that they can throw a (by-design) exception; whereas with methods, programmers are trained to expect and investigate whether exceptions are an expected consequence of invoking the method.
Getters are used by a lot of .NET infrastructure, like serializers and databinding (in WinForms and WPF for example) - dealing with exceptions in such contexts can rapidly become problematic.
Property getters are automatically evaluated by debuggers when you watch or inspect an object. An exception here can be confusing and slow down your debugging efforts. It's also undesirable to perform other expensive operations in properties (like accessing a database) for the same reasons.
Properties are often used in a chaining convention: obj.PropA.AnotherProp.YetAnother - with this kind of syntax it becomes problematic to decide where to inject exception catch statements.
As a side note, one should be aware that just because a property is not designed to throw an exception, that doesn't mean it won't; it could easily be calling code that does. Even the simple act of allocating a new object (like a string) could result in exceptions. You should always write your code defensively and expect exceptions from anything you invoke.
There's nothing wrong with throwing exceptions from setters. After all, what better way to indicate that the value is not valid for a given property?
For getters, it is generally frowned upon, and that can be explained pretty easily: a property getter, in general, reports the current state of an object; thus, the only case where it is reasonable for a getter to throw is when the state is invalid. But it is also generally considered to be a good idea to design your classes such that it is simply not possible to get an invalid object initially, or to put it into invalid state via normal means (i.e., always ensure full initialization in constructors, and try make methods exception-safe with respect to state validity and class invariants). So long as you stick to that rule, your property getters should never get into a situation where they have to report invalid state, and thus never throw.
There is one exception I know of, and it's actually a rather major one: any object implementing IDisposable. Dispose is specifically intended as a way to bring object into an invalid state, and there's even a special exception class, ObjectDisposedException, to be used in that case. It is perfectly normal to throw ObjectDisposedException from any class member, including property getters (and excluding Dispose itself), after the object has been disposed.
It is almost never appropriate on a getter, and sometimes appropriate on a setter.
The best resource for these sorts of questions is "Framework Design Guidelines" by Cwalina and Abrams; it's available as a bound book, and large portions of it are also available online.
From section 5.2: Property Design
AVOID throwing exceptions from
property getters. Property getters
should be simple operations and should
not have preconditions. If a getter
can throw an exception, it should
probably be redesigned to be a method.
Note that this rule does not apply to
indexers, where we do expect
exceptions as a result of validating
the arguments.
Note that this guideline only applies
to property getters. It is OK to throw
an exception in a property setter.
This is all documented in MSDN (as linked to in other answers) but here is a general rule of thumb...
In the setter, if your property should be validated above and beyond type. For example, a property called PhoneNumber should probably have regex validation and should throw an error if the format is not valid.
For getters, possibly when the value is null, but most likely that is something you will want to handle on the calling code (per the design guidelines).
One nice approach to Exceptions is to use them to document code for yourself and other developers as follows:
Exceptions should be for exceptional program states. This means it's fine to write them wherever you want!
One reason you might want to put them in getters is to document the API of a class - if the software throws an exception as soon as a programmer tries to use it wrong then they wont use it wrong! For instance if you have validation during a data reading process it may not make sense to be able to continue and access the results of the process if there were fatal errors in the data. In this case you may want to make getting the output throw if there were errors to ensure that another programmer checks for this condition.
They are a way of documenting the assumptions and boundaries of a subsystem/method/whatever. In the general case they should not be caught! This is also because they are never thrown if the system is working together in the way expected: If an exception happens it shows that the assumptions of a piece of code are not met - eg it is not interacting with the world around it in the way it was originally intended to. If you catch an exception that was written for this purpose it probably means the system has entered an unpredictable/inconsistent state - this may ultimately lead to a crash or corruption of data or similar which is likely to be much harder to detect/debug.
Exception messages are a very coarse way of reporting errors - they cannot be collected en-masse and only really contain a string. This makes them unsuitable for reporting problems in input data. In normal running the system itself should not enter an error state. As a result of this the messages in them should be designed for programmers and not for users - things that are wrong in input data can be discovered and relayed to users in more suitable (custom) formats.
The Exception (haha!) to this rule is things like IO where exceptions are not under your control and cannot be checked for in advance.
MSDN: Catching and Throwing Standard Exception Types
http://msdn.microsoft.com/en-us/library/ms229007.aspx
This is a very complex question and answer depends on how your object is used. As a rule of thumb, property getters and setters that are "late binding" should not throw exceptions, while properties with exclusively "early binding" should throw exceptions when the need arises. BTW, Microsoft's code analysis tool is defining the use of properties too narrowly in my opinion.
"late binding" means that properties are found through reflection. For example the Serializeable" attribute is used to serialize/deserialize an object via its properties. Throwing an exception during in this kind of situation breaks things in a catastrophic way and is not a good way of using exceptions to make more robust code.
"early binding" means that a property use is bound in the code by the compiler. For example when some code that you write references a property getter. In this case it is OK to throw exceptions when they make sense.
An object with internal attributes has a state determined by the values of those attributes. Properties expressing attributes that are aware and sensitive to the object's internal state should not be used for late binding. For example, lets say you have an object that must be opened, accessed, then closed. In this case accessing the properties without calling open first should result in an exception. Suppose, in this case, that we do not throw an exception and we allow the code access to a value without throwing an exception? The code will seem happy even though it got a value from a getter that is non-sense. Now we have put the code that called the getter in a bad situation since it must know how to check the value to see if it is non-sense. This means that the code must make assumptions about the value that it got from the property getter in order to validate it. This is how bad code gets written.
I had this code where I was unsure of which exception to throw.
public Person
{
public string Name { get; set; }
public boolean HasPets { get; set; }
}
public void Foo(Person person)
{
if (person.Name == null) {
throw new Exception("Name of person is null.");
// I was unsure of which exception to throw here.
}
Console.WriteLine("Name is: " + person.Name);
}
I prevented the model from having the property being null in the first place by forcing it as an argument in the constructor.
public Person
{
public Person(string name)
{
if (name == null) {
throw new ArgumentNullException(nameof(name));
}
Name = name;
}
public string Name { get; private set; }
public boolean HasPets { get; set; }
}
public void Foo(Person person)
{
Console.WriteLine("Name is: " + person.Name);
}

Categories