Closed carandraug closed 4 years ago
I've looked at all the exceptions currently being raised in microscope and here's what I've found.
First the easy ones that I have already handled with builtin exceptions:
raising exception because function was called incorrectly, either arguments of
the wrong type, wrong combination of arguments (when there's more than one way
to call a function but some arguments are incompatible), or too many or too
little arguments (in the case of using *args, **kwargs). These cases are all
covered by the builtin TypeError
exception so I already made that change.
raising exception because the argument for a function was the right type but
wrong value such as setting the ROI of a camera larger than the sensor size.
This is covered by the builtin ValueError
exception so I already made that
change.
The others are a bit more complex and I think some can be grouped:
failure to connect to a device during initialize (either the device is missing (not connected), there is no device with that specific serial number, or the port was wrong).
serial commands returns a failure
serial commands does not return a failure but returns something unexpected
a controller device has multiple devices with the same name. This is
something that should not happen and would happen due to some bug in our code
so I think should be replaced with an assert
.
some option is unknown (this happens on the pvcam because the settings are generated dynamically but for some reason some option is missing from the dll)
dll function returns failure
error wrapping dll function
timeouts (either from serial commands, but also some dll functions)
device instance is in an unexpected state (this is in code not in hardware, e.g., setting the trigger should check if the trigger mode is valid, but at some point later the trigger mode is set to something that should have been filtered before). I propose that this is replaced with assertions, since this probably indicates a logic problem in our code.
purging camera buffer during acquisition (acquisition must be stopped for that to work). This is effectively device being at the wrong state for the function.
calling methods that only work after device has been initialized, enabled, or set to a certain trigger type. Like above, this is the device being at the wrong state for the action.
missing license for the SDK
some Pyro setting has been disabled by the user for some reason
device server program called with an invalid config.
the device server is missing details for a found floating device. I guess this is invalid/missing configuration but its only raised much later, on the separate process of that device.
Taken this into account, here's the exceptions I propose:
MicroscopeError
+-- DeviceError
| +-- IncompatibleStateError
| | +-- DisabledDeviceError
| +-- InitialiseError
| +-- possibly to further subclass later (see below)
+-- LibraryLoadError
DeviceError
this is for issues controlling the device, both in controlling
via the software but also hardware errors. At the base level it includes both
serial and dll errors and unexpected reply which later may go on their own
subclasses.
IncompatibleStateError
when something is attempted but the device is on the
wrong state for that action. Because the device being disabled is such a
specific case with a specific handling, I think that DisabledDeviceError
should also exist as a subclass.
InitialiseError
for cases where the device fails to connect because it's
already initialized elsewhere or maybe missing (we can later have a separate
class for NoSuchDeviceError
that subclasses this and be backwards compatible
but I don't think it'll be needed). There are a few Connection*Error
builtin exceptions but they seem to be really aimed at network sockets.
LibraryLoadError
for cases where a dll fails to load for some reason. This
also includes the construction of the CDLL
object which at the moment we
don't handle and fails with a cryptic OSError
. This would exception would
also include failures during the init of the library such as missing the
license file for the linkam or failure of the SDK3 InitializeLibrary
function, as well failure to wrap some function (which probably means that the
library has changed somehow)
Use ValueError
for issues on the device server configuration file
TimeoutError
not sure whether we should be using the builtin TimeoutError
exception, but I'm learning towards the builtin error.
Now done.
I think it would be nice to have specific exceptions for microscope. I'm constantly thinking it would be nice to have a specific exception class for cases but end up either raising a general
Exception
orRuntimeException
because it's too much trouble thinking about the exception hierarchy we should have.It's easy to fall in the trap of having too many exception types, one for each case. It's hard to get the balance right but I guess the only way to find out is to start doing it and adjusting over time. I propose we create a base
MicroscopeException
and start from there and trim down later. We can recommend users to only catch the base microscope exception in order to not worry about keeping backwards compatible.Some of the exceptions I would like are: