From ef428ff39f0962141ab50e93b0b8af44efaee9c0 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Thu, 6 Apr 2023 16:21:25 -0300 Subject: [PATCH] Subscription.Fire() can error, so Relay.Subscribe() must also. --- relay.go | 29 ++++++++++++++++++++--------- subscription.go | 3 ++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/relay.go b/relay.go index 83bc3d3..b22d5c3 100644 --- a/relay.go +++ b/relay.go @@ -301,7 +301,11 @@ func (r *Relay) Publish(ctx context.Context, event Event) (Status, error) { return status, err } - sub := r.Subscribe(ctx, Filters{Filter{IDs: []string{event.ID}}}) + sub, err := r.Subscribe(ctx, Filters{Filter{IDs: []string{event.ID}}}) + if err != nil { + return status, fmt.Errorf("failed to subscribe to just published event %s at %s: %w", event.ID, r.URL, err) + } + for { select { case receivedEvent := <-sub.Events: @@ -389,20 +393,27 @@ func (r *Relay) Auth(ctx context.Context, event Event) (Status, error) { // Subscribe sends a "REQ" command to the relay r as in NIP-01. // Events are returned through the channel sub.Events. // The subscription is closed when context ctx is cancelled ("CLOSE" in NIP-01). -func (r *Relay) Subscribe(ctx context.Context, filters Filters) *Subscription { +func (r *Relay) Subscribe(ctx context.Context, filters Filters) (*Subscription, error) { if r.Connection == nil { panic(fmt.Errorf("must call .Connect() first before calling .Subscribe()")) } sub := r.PrepareSubscription(ctx) sub.Filters = filters - sub.Fire() - return sub + if err := sub.Fire(); err != nil { + return nil, fmt.Errorf("couldn't subscribe to %v at %s: %w", filters, r.URL, err) + } + + return sub, nil } -func (r *Relay) QuerySync(ctx context.Context, filter Filter) []*Event { - sub := r.Subscribe(ctx, Filters{filter}) +func (r *Relay) QuerySync(ctx context.Context, filter Filter) ([]*Event, error) { + sub, err := r.Subscribe(ctx, Filters{filter}) + if err != nil { + return nil, err + } + defer sub.Unsub() if _, ok := ctx.Deadline(); !ok { @@ -418,13 +429,13 @@ func (r *Relay) QuerySync(ctx context.Context, filter Filter) []*Event { case evt := <-sub.Events: if evt == nil { // channel is closed - return events + return events, nil } events = append(events, evt) case <-sub.EndOfStoredEvents: - return events + return events, nil case <-ctx.Done(): - return events + return events, nil } } } diff --git a/subscription.go b/subscription.go index d4ac5a9..a6632da 100644 --- a/subscription.go +++ b/subscription.go @@ -2,6 +2,7 @@ package nostr import ( "context" + "fmt" "strconv" "sync" ) @@ -70,7 +71,7 @@ func (sub *Subscription) Fire() error { err := sub.conn.WriteJSON(message) if err != nil { sub.cancel() - return err + return fmt.Errorf("failed to write: %w", err) } // the subscription ends once the context is canceled