Reputation: 5294
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?
Upvotes: 0
Views: 970
Reputation: 81105
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.
Upvotes: 2
Reputation: 38397
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...
Upvotes: 3
Reputation: 161773
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));
Upvotes: 2
Reputation: 47038
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.
Upvotes: 0