Open glopesdev opened 2 months ago
The solutions above are still "naive" in the sense they assume integrity of editor state for the current action following an unhandled exception.
In other words, if a command crashes as part of a composite, it is true that the previous commands could be "undone", but it will remain unclear what to do with side-effects of the currently executing "partial" command. Should its own "undo" action be called? Probably not, since the command did not fully finish and there is a high chance that it may crash itself or leave the editor in a corrupt state. However, by the same reason we shouldn't undo the previous commands either, since we can be half-way between modifying the editor state and therefore in violation of the state integrity assumptions of the undo/redo stack.
Sadly, it seems there is no easy way out other than to ensure that commands and their respective undo operations do not throw. If they do, that must be always considered a critical regression and the issue will have to be identified and fixed.
Any approach other than this will likely require reimagining how to model the state of the editor to give it more functional and immutability guarantees so we could have partial snapshots at any point.
Several commands in the IDE are "composite", meaning that they are logged in the undo/redo stack as a single command. They are defined as lists of regular commands sandwiched in between
BeginComposite
andEndComposite
calls.Unfortunately, if an unhandled exception is thrown by the IDE before the
EndComposite
call, the entire IDE will be blocked, since it is not possible to callBeginComposite
before the previousEndComposite
is closed. This situation should be detected and the command history either reset or unwound to unblock the situation.Possible solutions include:
EndComposite
before throwing the exception, to ensure subsequent commands can be raised if the exception is caught;EndComposite
, to avoid corrupted editor state;