Found while fixing #1567.
#1567 was one instance of a general shape. Across src/, roughly a dozen onClick(async () => …) / onclick={async …} handlers hand Obsidian (or Svelte) a promise that is then discarded. Anything that throws inside one of them - not just a prompt cancellation - lands in the console as Uncaught (in promise) … with no notice, no log entry, and no indication to the user that the action failed.
Examples of the shape (not an exhaustive list):
src/gui/AIAssistantProvidersModal.ts - the add-provider / add-model handlers
src/gui/MacroGUIs/CommandSequenceEditor.ts - deleteCommand also does throw new Error("command not found")
src/gui/choiceList/ChoiceView.svelte - deleteChoice and friends, passed as props into click handlers
#1567 fixed the cause for one modal by making it stop rejecting. That is the right fix there, but it does not generalise: the next genuine failure in any of these handlers still disappears into the console.
Shape of a fix: one seam, not a dozen try/catch blocks. Either a small runAction(fn) helper that handlers are routed through (reporting non-cancellation errors via reportError and swallowing cancellations), or a global unhandledrejection reporter registered on plugin load. Worth deciding which, because the per-handler version is exactly the boilerplate that failed to converge in #1567.
Found while fixing #1567.
#1567 was one instance of a general shape. Across
src/, roughly a dozenonClick(async () => …)/onclick={async …}handlers hand Obsidian (or Svelte) a promise that is then discarded. Anything that throws inside one of them - not just a prompt cancellation - lands in the console asUncaught (in promise) …with no notice, no log entry, and no indication to the user that the action failed.Examples of the shape (not an exhaustive list):
src/gui/AIAssistantProvidersModal.ts- the add-provider / add-model handlerssrc/gui/MacroGUIs/CommandSequenceEditor.ts-deleteCommandalso doesthrow new Error("command not found")src/gui/choiceList/ChoiceView.svelte-deleteChoiceand friends, passed as props into click handlers#1567 fixed the cause for one modal by making it stop rejecting. That is the right fix there, but it does not generalise: the next genuine failure in any of these handlers still disappears into the console.
Shape of a fix: one seam, not a dozen
try/catchblocks. Either a smallrunAction(fn)helper that handlers are routed through (reporting non-cancellation errors viareportErrorand swallowing cancellations), or a globalunhandledrejectionreporter registered on plugin load. Worth deciding which, because the per-handler version is exactly the boilerplate that failed to converge in #1567.