allen-cell-animated / volume-viewer

https://allen-cell-animated.github.io/volume-viewer/
Other
90 stars 7 forks source link

Propagate load errors #215

Closed frasercl closed 2 months ago

frasercl commented 2 months ago

Review time: moderate (~30min)

210 introduced a new VolumeLoadError type to let us rigorously express any errors that might happen while loading volume data. But due to multiple problems with the way volume loading works, not all of those errors were actually possible to catch. This PR makes changes to ensure that, no matter where errors happen, a client package (i.e. website-3d-cell-viewer) always has a way to learn about it.

Problem 1: Callbacks

When a loader loads volume data (as opposed to metadata), we generally make simultaneous requests for every individual channel (or batch of channels) in a volume. Internally, this looks like firing off an async closure for every (batch of) channels we're trying to load and then immediately returning, relying on a callback to get channel data back once it's loaded. Trouble is, those closures end up basically floating in space with no connection back to the original call that initiated them.

To resolve this, I changed the signature of loadVolumeData to return a Promise<void> which represents the load operation in progress, and which therefore must only resolve when all requested channels have loaded. Assuming that promise is implemented sensibly, if one of those channel loads errors, that error should result in the promise rejecting, letting anyone await-ing the promise catch that error.

Implementing this required a moderate rework to the way ThreadableVolumeLoader works, and therefore to the interface between VolumeLoadWorker and the main thread (via VolumeLoaderContext).

Problem 2: Implicit loading

Even if every error generated by a loader can be caught, not every call to the loader is accessible to the client: many (most now) are made implicitly on a change to some other setting - time, region, scale level, etc. I added the ability to set a load error handler on View3d to capture errors on these implicit loads. This handler gets attached to a Volume via the pre-existing VolumeDataObserver path.