proposal-signals icon indicating copy to clipboard operation
proposal-signals copied to clipboard

Exceptions in `watched` callback leave `Watcher` in inconsistent state

Open prophile opened this issue 1 year ago • 1 comments

Consider the following code:

const a = new Signal.State(0)
const b = new Signal.State(1, {
  [Signal.subtle.watched]: () => {
    throw new Error("this failed");
  },
})
const c = new Signal.State(2)

const watcher = new Signal.subtle.Watcher(() => {
  console.log("notified")
});
try {
  watcher.watch(a, b, c);
} catch (e) {
  console.log(e.message)
}

console.log("a sinks", Signal.subtle.introspectSinks(a))
console.log("b sinks", Signal.subtle.introspectSinks(b))
console.log("c sinks", Signal.subtle.introspectSinks(c))
console.log("watcher sources", Signal.subtle.introspectSources(watcher))

In the polyfill at f7c550b, and according to the algorithm in "Method: Signal.subtle.Watcher.prototype.watch(...signals)", this error thrown in the watched callback leaves Watcher in an inconsistent state. a has the watcher as a sink but neither b nor c do (so we have a case where watcher.watch has added some, but not all, of its arguments as sources); also, the watcher lists both a and b as sources so its state is inconsistent as to whether b is watched or not.

prophile avatar Apr 29 '24 18:04 prophile

Not fixed by https://github.com/tc39/proposal-signals/pull/223 . What should we do about multiple exceptions? Should we unwind everything?

littledan avatar May 28 '24 15:05 littledan