tc39 / proposal-cancelable-promises

Former home of the now-withdrawn cancelable promises proposal for JavaScript
Other
375 stars 29 forks source link

Alternatives for suppressing death throes #9

Closed dtribble closed 8 years ago

dtribble commented 8 years ago

Death throes refers to the explosion of exceptions that can be generated when a system has computation abruptly terminate, typically as a result of cancellation or system shutdown. The proposal clearly takes as a requirement to suppress death throes, which I agree is crucial to cancellation handling.

However the proposed mechanism addresses the death throes with an additional promise result state. I think that's both more complicated than needed and not sufficiently general. It also breaks a primary use case of error handling: called methods can signal an error with a claim of being "cancelled" and thereby skip the callers error handling and cleanup, thus preventing a caller from correctly reestablishing invariants.

Additionally, all the considerations of suppressing routine exception handling occur in simpler case without promises; e.g., where a system is shutting down or a browser page is being changed. The rendering contexts are broken, the DNS library has dropped it's cache, the log file is closed, etc. Essentially stable elements of the application or service are getting invoked when the "invariants" of the environment have been compromised.

So a couple of other possible directions to go that generalize to promises without requiring any specific change in promises (though of course some may still be desirable).

1) Add a cancelling state to error objects. Add a test for that in try/catch.

  try {
    await fetch(...);
  } onCancel (e) {
    debugLog(e.message);
  } catch (e) {
    showUserMessage("The site is down.");
  } finally {
    stopLoadingSpinner();
  }

This strategy is useful for code across the system, not just promises. However it has the same characteristic as the 3rd state does: it requires dynamic signalling. In typical cancellation and shutdown scenarios, the error handling site has knowledge of whether it's shutting down, cancelling, or otherwise no longer cares about error handling. Hence the test should not be about the error, but rather about something in the lexical scope.

2) Suppress death throes in the error handlers. Extend the try-catch construct with an environmental tests.

try {
  await fetch(...);
} suppressIf (myToken.isCancelling) {
  debugLog(myToken.reason);
} catch (e) {
  showUserMessage("The site is down.");
} finally {
  stopLoadingSpinner();
}

There's lots of syntactic options for this (e.g., catch (e) unless (myToken.isCancelling).. or onCancel(myToken)), so the real focus is on what source the information that normal error handling should be suppressed is. From a design point of view, having it clearly delineated in code is clarifying.

domenic commented 8 years ago

New approach should address these concerns.