Possible approaches
// synchronous
try {
keen.captureCompound();
keen.execute('CMD');
keen.execute('CMD');
keen.finishCompound();
} catch (exception) {
keen.cancelCompound();
}
Isolated commands
With isolated commands, as it currently works, the onus is on the caller to check for errors at each and every execution point, the same as with synchronous commands. However, because exceptions can't be used, it's much more verbose than with synchronous:
keen.captureCompound().then(function () {
return keen.execute('CMD');
}).then(function () {
return keen.execute('CMD');
}).then(function () {
return keen.finishCompound();
}).fail(function (err) {
return keen.cancelCompound();
});
Bubbling errors
Another simple approach would be to just chain all deferred actions together and to bubble errors through, effectively cancelling any queued actions present after the point of error.
keen.captureCompound();
keen.execute('CMD');
keen.execute('CMD');
keen.finishCompound().fail(function (err) {
keen.cancelCompound();
});
keen.execute('UNRELATED_CMD');
For this to work reliably, the failure would have to persist so that actions added after the point of failure would properly bubble errors. (Would be easy to implement, by just chaining deferred functions with 'then', so every deferred is just added to a long promise chain). This gives no way to trap an error and carry on afterwards, however.
Command error handling
Another approach would be to keep the persistent bubbling, but manually set it up such that deferreds can choose to handle errors. The semantics would be similar to express routing error bubbling, whereby the error would be propagated until an action was found that handled errors. This would allow:
keen.captureCompound();
keen.execute('CMD');
keen.execute('CMD');
keen.finishCompound();
keen.handleError(function (err) {
keen.cancelCompound();
});
keen.execute('UNRELATED_CMD');
(In an actual implementation, finishCompound would likely bundle the cancelling of a compound which errored. Would be good to allow commands to specify their own error handlers, ideally allowing a command to retry or cancel, as well as choose to propagate the error further.)
Possible approaches
Isolated commands
With isolated commands, as it currently works, the onus is on the caller to check for errors at each and every execution point, the same as with synchronous commands. However, because exceptions can't be used, it's much more verbose than with synchronous:
Bubbling errors
Another simple approach would be to just chain all deferred actions together and to bubble errors through, effectively cancelling any queued actions present after the point of error.
For this to work reliably, the failure would have to persist so that actions added after the point of failure would properly bubble errors. (Would be easy to implement, by just chaining deferred functions with 'then', so every deferred is just added to a long promise chain). This gives no way to trap an error and carry on afterwards, however.
Command error handling
Another approach would be to keep the persistent bubbling, but manually set it up such that deferreds can choose to handle errors. The semantics would be similar to express routing error bubbling, whereby the error would be propagated until an action was found that handled errors. This would allow:
(In an actual implementation, finishCompound would likely bundle the cancelling of a compound which errored. Would be good to allow commands to specify their own error handlers, ideally allowing a command to retry or cancel, as well as choose to propagate the error further.)