ignore error when sending on a CLOSE to a closed connection.

This commit is contained in:
fiatjaf
2025-05-31 12:29:24 -03:00
parent de26ee98c5
commit 5b78a829c7
3 changed files with 22 additions and 7 deletions

View File

@@ -1,6 +1,6 @@
/* global WebSocket */ /* global WebSocket */
import type { Event, EventTemplate, VerifiedEvent, Nostr } from './core.ts' import type { Event, EventTemplate, VerifiedEvent, Nostr, NostrEvent } from './core.ts'
import { matchFilters, type Filter } from './filter.ts' import { matchFilters, type Filter } from './filter.ts'
import { getHex64, getSubscriptionId } from './fakejson.ts' import { getHex64, getSubscriptionId } from './fakejson.ts'
import { Queue, normalizeURL } from './utils.ts' import { Queue, normalizeURL } from './utils.ts'
@@ -12,6 +12,13 @@ export type AbstractRelayConstructorOptions = {
websocketImplementation?: typeof WebSocket websocketImplementation?: typeof WebSocket
} }
export class SendingOnClosedConnection extends Error {
constructor(message: string, relay: string) {
super(`Tried to send message '${message} on a closed connection to ${relay}.`)
this.name = 'SendingOnClosedConnection'
}
}
export class AbstractRelay { export class AbstractRelay {
public readonly url: string public readonly url: string
private _connected: boolean = false private _connected: boolean = false
@@ -112,7 +119,7 @@ export class AbstractRelay {
} }
} }
this.ws.onclose = (ev) => { this.ws.onclose = ev => {
clearTimeout(this.connectionTimeoutHandle) clearTimeout(this.connectionTimeoutHandle)
reject((ev as any).message || 'websocket closed') reject((ev as any).message || 'websocket closed')
if (this._connected) { if (this._connected) {
@@ -178,7 +185,7 @@ export class AbstractRelay {
switch (data[0]) { switch (data[0]) {
case 'EVENT': { case 'EVENT': {
const so = this.openSubs.get(data[1] as string) as Subscription const so = this.openSubs.get(data[1] as string) as Subscription
const event = data[2] as Event const event = data[2] as NostrEvent
if (this.verifyEvent(event) && matchFilters(so.filters, event)) { if (this.verifyEvent(event) && matchFilters(so.filters, event)) {
so.onevent(event) so.onevent(event)
} }
@@ -236,7 +243,7 @@ export class AbstractRelay {
} }
public async send(message: string) { public async send(message: string) {
if (!this.connectionPromise) throw new Error('sending on closed connection') if (!this.connectionPromise) throw new SendingOnClosedConnection(message, this.url)
this.connectionPromise.then(() => { this.connectionPromise.then(() => {
this.ws?.send(message) this.ws?.send(message)
@@ -379,7 +386,15 @@ export class Subscription {
if (!this.closed && this.relay.connected) { if (!this.closed && this.relay.connected) {
// if the connection was closed by the user calling .close() we will send a CLOSE message // if the connection was closed by the user calling .close() we will send a CLOSE message
// otherwise this._open will be already set to false so we will skip this // otherwise this._open will be already set to false so we will skip this
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + ']') try {
this.relay.send('["CLOSE",' + JSON.stringify(this.id) + ']')
} catch (err) {
if (err instanceof SendingOnClosedConnection) {
/* doesn't matter, it's ok */
} else {
throw err
}
}
this.closed = true this.closed = true
} }
this.relay.openSubs.delete(this.id) this.relay.openSubs.delete(this.id)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@nostr/tools", "name": "@nostr/tools",
"version": "2.13.2", "version": "2.13.3",
"exports": { "exports": {
".": "./index.ts", ".": "./index.ts",
"./core": "./core.ts", "./core": "./core.ts",

View File

@@ -1,7 +1,7 @@
{ {
"type": "module", "type": "module",
"name": "nostr-tools", "name": "nostr-tools",
"version": "2.13.2", "version": "2.13.3",
"description": "Tools for making a Nostr client.", "description": "Tools for making a Nostr client.",
"repository": { "repository": {
"type": "git", "type": "git",