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