Exception Class Visibility? - c#

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).

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?

Need help to get out of the exception jungle

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).
}

What does "throw new NotImplementedException();" do exactly?

I have a class 'b' that inherits from class 'a'. In class 'a' there is some code that performs an action if an event is not null. I need that code to fire in class 'b' during specific times in the application. So in 'b' I subscribed to a new Handler(event).
If I leave the autogenerated event 'as is' in class 'b' with the throw new NotImplementedException(); line, the code works/runs as expected. As soon as I remove the thow exception, the application no longer works as expected.
So, what is the throw new NotImplementedException doing besides throwing the exception?
I realize I'm probably trying to solve my coding problem the wrong way at this point, and I am sure I will find a better way to do it (I'm still learning), but my question remains. Why does that line change the outcome of code?
EDIT:
I reallize I wan't very specific with my code. Unfortunately, because of strict policies, I can't be. I have in class 'a' an if statement.
if (someEvent != null)
When the code 'works', the if statement is returning true. When it isn't working as expected, it is returning 'false'. In class 'b', the only time the application 'works' (or the if statement returns true), is when I have the throw new NotImplementedException(); line in class 'b's event method that is autogenerated when I attached the new event.
Think about this: what if you want to add two integers with the following method...
private int Add(int x, int y)
{
}
...and have no code inside to do such (the method doesn't even return an integer). This is what NotImplementedException is used for.
NotImplementedException is simply an exception that is used when the code for what you're trying to do isn't written yet. It's often used in snippets as a placeholder until you fill in the body of whatever has been generated with actual code.
It's good practice to use a NotImplementedException as opposed to an empty block of code, because it will very clearly throw an error alerting you that section of your code isn't complete yet. If it was blank, then the method might run and nothing would happen, and that's a pain to debug sometimes.
It is simply an exception, as for why it means your application "works" is entirely dependent on the code handling any exceptions.
It is not a "special" exception as opposed to a normal exception (other than being derived from Exception like the rest). You tend to see it with code generation as a placeholder for implementing the member it is throwing inside. It is a lot easier to do this than have code generation try to understand the member structure in order to output compiling code.
When you say "no longer works as expected", I am assuming it compiles. If removing this stops the code from compiling then the chances are good you have a compilation error about a return value.
Perhaps the code that triggers the event expects a certain response from handlers, or if there are no handlers or exceptions occur it defaults the response and carries on. In your case, there is a handler and no exception so it expects a better response?
Complete guesswork.
If there is code in a that you need to use in b, consider making the method that houses the code protected and optionally virtual if you need to override the behaviour.
NotImplementedException, I believe, has a little special meaning: "this code is still in development and needs to be changed". Developers put this exception to make some code compileable, but not executable (to avoid data damage).
Information about this exception type can be found in documentation, it explains the meaning very detailed: https://learn.microsoft.com/en-us/dotnet/api/system.notimplementedexception?view=netcore-3.1
Some development tools, like Resharper, for example, generates new members with NotImplementedException inside, thus protecting you from execution the code, which is not ready. Same time they highlight this exceptions same way as "//todo:" comment
For other situations, for example, when you don't need to implement an interface or virtual member, or may be, you don't implement some paths in switch/case, if/else etc statements, you probably will use NotSupportedException, OutOfRangeException, ArgumentNullException, InvalidOperationException etc.
At the end, consider this situation to understand the purpose of NotImplementedException:
We are writing banking application, and, at the moment, implementing money transferring feature, we have:
public void Transfer(sourceAccount, destAccount, decimal sum)
{
sourceAccount.Credit(sum);
destAccount.Debit(sum);
}
Here we are calling two methods which do not exist yet. We are generating both with default NotImplementedException, and going to first one (Credit) to implement it. Lets say, implementation took some time, we have written test for it, and even have done several manual tests. We completely forgot about second method "Debit" and deploying our application to beta, or even to production. Testers or users start using our application and soon they are coming to money transfer functionality. They are trying to call Transfer, which shows them a general message "We are so sorry, we got some errors", same time we, as a developer team, receive notification about NotImplementedException happened with the stack trace pointing us to the method "Debit". Now we are implementing it, and releasing new version, which can do money transfers.
Now imagine, what would happen, if there was not an exception there: users would spend lot of money trying to do that transfers, trying several times, each time throwing money in to a hole.
Depending on the purposes of the application it can be bigger or smaller problem: may be button on your calculator does not work, or may be that was scientific calculator and we just missed some important math while calculating vaccine code against some aggressive virus.
The NotImplementedException is a way of declaring that a particular method of an interface or base class is simply not implemented in your type. This is the exception form of the E_NOTIMPL error code.
In general an implementation shouldn't be throwing a NotImplementedException unless it's a specifically supported scenario for that particular interface. In the vast majority of scenarios this is not the case and types should fully implement interfaces.
In terms of what it's doing though. It's simply throwing an exception. It's hard to say why the program keeps function in the face of the exception and breaks without it unless you give us a bit more information.

Custom Exception class

I have an abstract class Camera. There are some derived classes that will handle specific types of cameras. Every type of camera does has its own exceptions, while some of them do not have exceptions at all, they return an enum with error type.
I want to know if you people agree with this implementation:
All specific classes will handle their exceptions (or enum error type) and will convert it to a generic exception (ex: CameraException : Exception) and throw it.
Is it a good/recommended implementation?
You would want to unify the error concepts into a common CameraException class hierarchy. If the goal is to abstract the camera implementaiton, you should abstract the errors as well into this common exception framework.
If you have only implementation-specific exceptions, then it will be very hard for a user of your class to understand exactly what the CameraException is trying to say without analyzing the details.
I'd recommend providing a framework of logical exceptions, then your implementation-dependent camera logic will interpret the codes and then create the correct corresponding logical camera exception.
For instance, if you try and perform an operation on the camera's memory, card, and none is inserted, throw a NoMemoryCardInCameraException which can inherit from CameraException.
If you really want those provider details to be available, you could have a property in CameraException called Detail or something that would be an abstract class or a Dictionary of key value pairs with implementation specific details. That way if someone really wants to dig into the actual error codes, enums, etc from the provider they can.
Your goal should be for the average user to be able to catch logical exceptions and handle them appropriately w/o needing to know the specifics.
Hope that clarifies it a bit...
Application layers should define custom exception types, regardless of what Microsoft says. Suppose one has an abstract WrappedCamera class, derivatives of which which serve as wrappers around classes like CanonCamera, NikonCamera, KodakCamera, and future derivatives of which will serve as wrappers around classes for cameras designed in future. Suppose that a class WrappedWaldorfCamera wraps WaldorfCamera, and when it calls WaldorfCamera.GetPictureCount() that method throws exception WaldorfCamera.WrongCameraModeException. If WrappedWaldorfCamera lets the exception percolate up, what is an application going to do with it? Unless the application assumes that all unknown exception types should display a message but allow the program to continue, there's no way the application could know that a WaldorfCamera.WrongCameraModeException was safe to catch. By contrast, if WrappedWaldorfCamera were to throw a WrappedCamera.CameraModeException which derived from WrappedCamera.CleanNonConnectStateException, an application would know that it should catch the exception and handle it.
BTW, lest anyone complain that the whole "problem" was created by WaldorfCamera defining its own exception, consider the situation if instead WrappedWaldorfCamera let percolate an InvalidOperationException. What should an application do with one of those?
The proper thing to do is for each application layer to define at, at minimum, fatal and non-fatal exception types--typically with a few flavors of each depending upon application state (e.g. CleanNonConnectStateException would imply that a particular camera-connection object doesn't have a valid connection; application code which is prepared to deal with that should catch the exception, while code which isn't prepared to deal with that should let the exception bubble up to code that can handle the situation, rewrapping the exception if it crosses another layer boundary.
You should only create a new Exception type if a caller is going to catch that specific type, or if some caller is going to know about the specific type and look at it's properties.
If callers of the different camera types will do nothing more than this:
try
{
// Do something with some kind of camera
}
catch (CameraException ex)
{
// Handle the fact that there was a camera problem
}
Then there is no need for custom derived types of CameraException. Nobody cares what particular derived type was thrown.
In fact, if your callers will do nothing different when CameraException is thrown vs. any other kind of exception, then there is no need for a CameraException. Simply use something like InvalidOperationException and throw it with an informative Message property:
throw new InvalidOperationException(
String.Format("Invalid attempt to set the f-stop to {0} while in video mode",
this.FStop));
Converting to generic exceptions usually just hides important information.
Having all exceptions inherit CameraException can be a good thing, but let the different implementations subclass CameraException if they find it useful.

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