From 46255043cec21df58807db6ad9d169dc6e25c85f Mon Sep 17 00:00:00 2001 From: Patrick Mulligan Date: Sun, 25 Jan 2026 14:37:56 -0500 Subject: [PATCH] fix(nostr): update NostrSend type to Promise with error handling The NostrSend type was incorrectly typed as returning void when it actually returns Promise. This caused async errors to be silently swallowed. Changes: - Update NostrSend type signature to return Promise - Make NostrSender._nostrSend default to async function - Add .catch() error handling in NostrSender.Send() to log failures - Add logging to track event publishing status Co-Authored-By: Claude Opus 4.5 --- src/services/nostr/nostrPool.ts | 9 +++++---- src/services/nostr/sender.ts | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/services/nostr/nostrPool.ts b/src/services/nostr/nostrPool.ts index d41da382..d5e47d7f 100644 --- a/src/services/nostr/nostrPool.ts +++ b/src/services/nostr/nostrPool.ts @@ -16,7 +16,7 @@ export type SendDataContent = { type: "content", content: string, pub: string } export type SendDataEvent = { type: "event", event: UnsignedEvent, encrypt?: { toPub: string } } export type SendData = SendDataContent | SendDataEvent export type SendInitiator = { type: 'app', appId: string } | { type: 'client', clientId: string } -export type NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => void +export type NostrSend = (initiator: SendInitiator, data: SendData, relays?: string[] | undefined) => Promise export type LinkedProviderInfo = { pubkey: string, clientId: string, relayUrl: string } export type AppInfo = { appId: string, publicKey: string, privateKey: string, name: string, provider?: LinkedProviderInfo } @@ -203,21 +203,22 @@ export class NostrPool { const signed = finalizeEvent(event, Buffer.from(keys.privateKey, 'hex')) let sent = false const log = getLogger({ appName: keys.name }) - // const r = relays ? relays : this.getServiceRelays() + this.log(`📤 Publishing Kind ${event.kind} event to ${relays.length} relay(s): ${relays.join(', ')}`) const pool = new SimplePool() await Promise.all(pool.publish(relays, signed).map(async p => { try { await p sent = true } catch (e: any) { - console.log(e) + this.log(ERROR, `Failed to publish Kind ${event.kind} event:`, e.message || e) log(e) } })) if (!sent) { + this.log(ERROR, `Failed to send Kind ${event.kind} event to any relay`) log("failed to send event") } else { - //log("sent event") + this.log(`✅ Kind ${event.kind} event published successfully (id: ${signed.id.slice(0, 16)}...)`) } } diff --git a/src/services/nostr/sender.ts b/src/services/nostr/sender.ts index 1fd336a5..8437b9af 100644 --- a/src/services/nostr/sender.ts +++ b/src/services/nostr/sender.ts @@ -1,7 +1,7 @@ import { NostrSend, SendData, SendInitiator } from "./nostrPool.js" -import { getLogger } from "../helpers/logger.js" +import { ERROR, getLogger } from "../helpers/logger.js" export class NostrSender { - private _nostrSend: NostrSend = () => { throw new Error('nostr send not initialized yet') } + private _nostrSend: NostrSend = async () => { throw new Error('nostr send not initialized yet') } private isReady: boolean = false private onReadyCallbacks: (() => void)[] = [] private pendingSends: { initiator: SendInitiator, data: SendData, relays?: string[] | undefined }[] = [] @@ -12,7 +12,12 @@ export class NostrSender { this.isReady = true this.onReadyCallbacks.forEach(cb => cb()) this.onReadyCallbacks = [] - this.pendingSends.forEach(send => this._nostrSend(send.initiator, send.data, send.relays)) + // Process pending sends with proper error handling + this.pendingSends.forEach(send => { + this._nostrSend(send.initiator, send.data, send.relays).catch(e => { + this.log(ERROR, "failed to send pending event", e.message || e) + }) + }) this.pendingSends = [] } OnReady(callback: () => void) { @@ -22,13 +27,16 @@ export class NostrSender { this.onReadyCallbacks.push(callback) } } - Send(initiator: SendInitiator, data: SendData, relays?: string[] | undefined) { + Send(initiator: SendInitiator, data: SendData, relays?: string[] | undefined): void { if (!this.isReady) { this.log("tried to send before nostr was ready, caching request") this.pendingSends.push({ initiator, data, relays }) return } - this._nostrSend(initiator, data, relays) + // Fire and forget but log errors + this._nostrSend(initiator, data, relays).catch(e => { + this.log(ERROR, "failed to send event", e.message || e) + }) } IsReady() { return this.isReady