return error message from Publish()

This commit is contained in:
fiatjaf
2023-03-16 14:27:33 -03:00
parent 0765f7b91b
commit ec34d4eb10

View File

@@ -48,7 +48,7 @@ type Relay struct {
ConnectionError chan error ConnectionError chan error
ConnectionContext context.Context // will be canceled when the connection closes ConnectionContext context.Context // will be canceled when the connection closes
okCallbacks s.MapOf[string, func(bool)] okCallbacks s.MapOf[string, func(bool, string)]
// custom things that aren't often used // custom things that aren't often used
// //
@@ -195,12 +195,17 @@ func (r *Relay) Connect(ctx context.Context) error {
var ( var (
eventId string eventId string
ok bool ok bool
msg string
) )
json.Unmarshal(jsonMessage[1], &eventId) json.Unmarshal(jsonMessage[1], &eventId)
json.Unmarshal(jsonMessage[2], &ok) json.Unmarshal(jsonMessage[2], &ok)
if len(jsonMessage) > 3 {
json.Unmarshal(jsonMessage[3], &msg)
}
if okCallback, exist := r.okCallbacks.Load(eventId); exist { if okCallback, exist := r.okCallbacks.Load(eventId); exist {
okCallback(ok) okCallback(ok, msg)
} }
} }
} }
@@ -213,8 +218,9 @@ func (r *Relay) Connect(ctx context.Context) error {
// Publish sends an "EVENT" command to the relay r as in NIP-01. // Publish sends an "EVENT" command to the relay r as in NIP-01.
// Status can be: success, failed, or sent (no response from relay before ctx times out). // Status can be: success, failed, or sent (no response from relay before ctx times out).
func (r *Relay) Publish(ctx context.Context, event Event) Status { func (r *Relay) Publish(ctx context.Context, event Event) (Status, error) {
status := PublishStatusSent status := PublishStatusSent
var err error
// data races on status variable without this mutex // data races on status variable without this mutex
var mu sync.Mutex var mu sync.Mutex
@@ -232,13 +238,14 @@ func (r *Relay) Publish(ctx context.Context, event Event) Status {
defer cancel() defer cancel()
// listen for an OK callback // listen for an OK callback
okCallback := func(ok bool) { okCallback := func(ok bool, msg string) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
if ok { if ok {
status = PublishStatusSucceeded status = PublishStatusSucceeded
} else { } else {
status = PublishStatusFailed status = PublishStatusFailed
err = fmt.Errorf("msg: %s", msg)
} }
cancel() cancel()
} }
@@ -247,7 +254,7 @@ func (r *Relay) Publish(ctx context.Context, event Event) Status {
// publish event // publish event
if err := r.Connection.WriteJSON([]interface{}{"EVENT", event}); err != nil { if err := r.Connection.WriteJSON([]interface{}{"EVENT", event}); err != nil {
return status return status, err
} }
sub := r.Subscribe(ctx, Filters{Filter{IDs: []string{event.ID}}}) sub := r.Subscribe(ctx, Filters{Filter{IDs: []string{event.ID}}})
@@ -259,7 +266,7 @@ func (r *Relay) Publish(ctx context.Context, event Event) Status {
mu.Lock() mu.Lock()
status = PublishStatusSucceeded status = PublishStatusSucceeded
mu.Unlock() mu.Unlock()
return status return status, err
} }
case <-ctx.Done(): case <-ctx.Done():
// return status as it was // return status as it was
@@ -267,15 +274,16 @@ func (r *Relay) Publish(ctx context.Context, event Event) Status {
// e.g. if this happens because of the timeout then status will probably be "failed" // e.g. if this happens because of the timeout then status will probably be "failed"
// but if it happens because okCallback was called then it might be "succeeded" // but if it happens because okCallback was called then it might be "succeeded"
// do not return if okCallback is in process // do not return if okCallback is in process
return status return status, err
} }
} }
} }
// Auth sends an "AUTH" command client -> relay as in NIP-42. // Auth sends an "AUTH" command client -> relay as in NIP-42.
// Status can be: success, failed, or sent (no response from relay before ctx times out). // Status can be: success, failed, or sent (no response from relay before ctx times out).
func (r *Relay) Auth(ctx context.Context, event Event) Status { func (r *Relay) Auth(ctx context.Context, event Event) (Status, error) {
status := PublishStatusFailed status := PublishStatusFailed
var err error
// data races on status variable without this mutex // data races on status variable without this mutex
var mu sync.Mutex var mu sync.Mutex
@@ -293,12 +301,13 @@ func (r *Relay) Auth(ctx context.Context, event Event) Status {
defer cancel() defer cancel()
// listen for an OK callback // listen for an OK callback
okCallback := func(ok bool) { okCallback := func(ok bool, msg string) {
mu.Lock() mu.Lock()
if ok { if ok {
status = PublishStatusSucceeded status = PublishStatusSucceeded
} else { } else {
status = PublishStatusFailed status = PublishStatusFailed
err = fmt.Errorf("msg: %s", msg)
} }
mu.Unlock() mu.Unlock()
cancel() cancel()
@@ -309,7 +318,7 @@ func (r *Relay) Auth(ctx context.Context, event Event) Status {
// send AUTH // send AUTH
if err := r.Connection.WriteJSON([]interface{}{"AUTH", event}); err != nil { if err := r.Connection.WriteJSON([]interface{}{"AUTH", event}); err != nil {
// status will be "failed" // status will be "failed"
return status return status, err
} }
// use mu.Lock() just in case the okCallback got called, extremely unlikely. // use mu.Lock() just in case the okCallback got called, extremely unlikely.
mu.Lock() mu.Lock()
@@ -322,7 +331,7 @@ func (r *Relay) Auth(ctx context.Context, event Event) Status {
<-ctx.Done() <-ctx.Done()
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
return status return status, err
} }
// Subscribe sends a "REQ" command to the relay r as in NIP-01. // Subscribe sends a "REQ" command to the relay r as in NIP-01.