From e18321daea49170430da030c7afad83212102eac Mon Sep 17 00:00:00 2001 From: Bill Date: Fri, 7 Nov 2025 11:25:24 -0500 Subject: [PATCH] fix: improve promise handling in DOM event listeners Wrap async callbacks in void operators for DOM addEventListener calls to properly handle Promise returns in void contexts. This follows TypeScript best practices and Obsidian plugin guidelines. Changes: - settings.ts: Fix 5 button click handlers (server controls, API key actions, config copy) - notification-history.ts: Fix export button click handler All async operations are properly awaited within void-wrapped IIFEs, ensuring errors are not silently swallowed while maintaining the expected void return type for event listeners. --- src/settings.ts | 68 ++++++++++++++++++++-------------- src/ui/notification-history.ts | 18 +++++---- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/settings.ts b/src/settings.ts index b8d49e4..8f4ce37 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -146,22 +146,28 @@ export class MCPServerSettingTab extends PluginSettingTab { if (isRunning) { buttonContainer.createEl('button', {text: 'Stop Server'}) - .addEventListener('click', async () => { - await this.plugin.stopServer(); - this.display(); + .addEventListener('click', () => { + void (async () => { + await this.plugin.stopServer(); + this.display(); + })(); }); buttonContainer.createEl('button', {text: 'Restart Server'}) - .addEventListener('click', async () => { - await this.plugin.stopServer(); - await this.plugin.startServer(); - this.display(); + .addEventListener('click', () => { + void (async () => { + await this.plugin.stopServer(); + await this.plugin.startServer(); + this.display(); + })(); }); } else { buttonContainer.createEl('button', {text: 'Start Server'}) - .addEventListener('click', async () => { - await this.plugin.startServer(); - this.display(); + .addEventListener('click', () => { + void (async () => { + await this.plugin.startServer(); + this.display(); + })(); }); } @@ -215,21 +221,25 @@ export class MCPServerSettingTab extends PluginSettingTab { // Copy button const copyButton = apiKeyButtonContainer.createEl('button', {text: '📋 Copy Key'}); - copyButton.addEventListener('click', async () => { - await navigator.clipboard.writeText(this.plugin.settings.apiKey || ''); - new Notice('✅ API key copied to clipboard'); + copyButton.addEventListener('click', () => { + void (async () => { + await navigator.clipboard.writeText(this.plugin.settings.apiKey || ''); + new Notice('✅ API key copied to clipboard'); + })(); }); // Regenerate button const regenButton = apiKeyButtonContainer.createEl('button', {text: '🔄 Regenerate Key'}); - regenButton.addEventListener('click', async () => { - this.plugin.settings.apiKey = generateApiKey(); - await this.plugin.saveSettings(); - new Notice('✅ New API key generated'); - if (this.plugin.mcpServer?.isRunning()) { - new Notice('⚠️ Server restart required for API key changes to take effect'); - } - this.display(); + regenButton.addEventListener('click', () => { + void (async () => { + this.plugin.settings.apiKey = generateApiKey(); + await this.plugin.saveSettings(); + new Notice('✅ New API key generated'); + if (this.plugin.mcpServer?.isRunning()) { + new Notice('⚠️ Server restart required for API key changes to take effect'); + } + this.display(); + })(); }); // API Key display (static, copyable text) @@ -284,9 +294,11 @@ export class MCPServerSettingTab extends PluginSettingTab { text: '📋 Copy Configuration', cls: 'mcp-config-button' }); - copyConfigButton.addEventListener('click', async () => { - await navigator.clipboard.writeText(JSON.stringify(config, null, 2)); - new Notice('✅ Configuration copied to clipboard'); + copyConfigButton.addEventListener('click', () => { + void (async () => { + await navigator.clipboard.writeText(JSON.stringify(config, null, 2)); + new Notice('✅ Configuration copied to clipboard'); + })(); }); // Config JSON display @@ -413,9 +425,11 @@ export class MCPServerSettingTab extends PluginSettingTab { text: '📋 Copy Configuration', cls: 'mcp-config-button' }); - copyConfigButton.addEventListener('click', async () => { - await navigator.clipboard.writeText(JSON.stringify(config, null, 2)); - new Notice('✅ Configuration copied to clipboard'); + copyConfigButton.addEventListener('click', () => { + void (async () => { + await navigator.clipboard.writeText(JSON.stringify(config, null, 2)); + new Notice('✅ Configuration copied to clipboard'); + })(); }); // Config JSON display diff --git a/src/ui/notification-history.ts b/src/ui/notification-history.ts index a9a4135..16c49cf 100644 --- a/src/ui/notification-history.ts +++ b/src/ui/notification-history.ts @@ -162,14 +162,16 @@ export class NotificationHistoryModal extends Modal { // Export button const exportButton = actionsContainer.createEl('button', { text: 'Export to Clipboard' }); - exportButton.addEventListener('click', async () => { - const exportData = JSON.stringify(this.filteredHistory, null, 2); - await navigator.clipboard.writeText(exportData); - // Show temporary success message - exportButton.textContent = '✅ Copied!'; - setTimeout(() => { - exportButton.textContent = 'Export to Clipboard'; - }, 2000); + exportButton.addEventListener('click', () => { + void (async () => { + const exportData = JSON.stringify(this.filteredHistory, null, 2); + await navigator.clipboard.writeText(exportData); + // Show temporary success message + exportButton.textContent = '✅ Copied!'; + setTimeout(() => { + exportButton.textContent = 'Export to Clipboard'; + }, 2000); + })(); }); // Close button