diff --git a/indexedDb/impl/channels/callbacks.go b/indexedDb/impl/channels/callbacks.go index 68cc92d71f962ab4adc5d734f598561c95b006ea..4bcc3a64dda8d4d4c761c39ce30c5edfd656742f 100644 --- a/indexedDb/impl/channels/callbacks.go +++ b/indexedDb/impl/channels/callbacks.go @@ -340,8 +340,12 @@ func (m *manager) updateFromUUIDCB(data []byte) ([]byte, error) { status = &msg.Status } - m.model.UpdateFromUUID( + err = m.model.UpdateFromUUID( msg.UUID, messageID, timestamp, round, pinned, hidden, status) + if err != nil { + return []byte(err.Error()), nil + } + return nil, nil } @@ -374,15 +378,21 @@ func (m *manager) updateFromMessageIDCB(data []byte) ([]byte, error) { status = &msg.Status } - uuid := m.model.UpdateFromMessageID( + var ue wChannels.UuidError + uuid, err := m.model.UpdateFromMessageID( msg.MessageID, timestamp, round, pinned, hidden, status) + if err != nil { + ue.Error = []byte(err.Error()) + } else { + ue.UUID = uuid + } - uuidData, err := json.Marshal(uuid) + data, err = json.Marshal(ue) if err != nil { - return nil, errors.Errorf("failed to JSON marshal UUID : %+v", err) + return nil, errors.Errorf("failed to JSON marshal %T: %+v", ue, err) } - return uuidData, nil + return data, nil } // getMessageCB is the callback for wasmModel.GetMessage. Returns JSON diff --git a/indexedDb/impl/channels/implementation.go b/indexedDb/impl/channels/implementation.go index 803331357caa122fe00aaca7c77c296e21d4e3df..3f20a83666a5735f3e009741ea1d4358c9516855 100644 --- a/indexedDb/impl/channels/implementation.go +++ b/indexedDb/impl/channels/implementation.go @@ -251,10 +251,13 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID, // messageID, timestamp, round, pinned, and hidden are all nillable and may be // updated based upon the UUID at a later date. If a nil value is passed, then // make no update. +// +// Returns an error if the message cannot be updated. It must return +// channels.NoMessageErr if the message does not exist. func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, timestamp *time.Time, round *rounds.Round, pinned, hidden *bool, - status *channels.SentStatus) { - parentErr := errors.New("failed to UpdateFromUUID") + status *channels.SentStatus) error { + parentErr := "failed to UpdateFromUUID" // FIXME: this is a bit of race condition without the mux. // This should be done via the transactions (i.e., make a @@ -268,17 +271,18 @@ func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, // Use the key to get the existing Message currentMsg, err := impl.Get(w.db, messageStoreName, key) if err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to get message: %+v", err)) - return + if strings.Contains(err.Error(), impl.ErrDoesNotExist) { + return errors.WithMessage(channels.NoMessageErr, parentErr) + } + return errors.WithMessage(err, parentErr) } _, err = w.updateMessage(utils.JsToJson(currentMsg), messageID, timestamp, round, pinned, hidden, status) if err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to updateMessage: %+v", err)) + return errors.WithMessage(err, parentErr) } + return nil } // UpdateFromMessageID is called whenever a message with the message ID is @@ -290,10 +294,13 @@ func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, // timestamp, round, pinned, and hidden are all nillable and may be updated // based upon the UUID at a later date. If a nil value is passed, then make // no update. +// +// Returns an error if the message cannot be updated. It must return +// channels.NoMessageErr if the message does not exist. func (w *wasmModel) UpdateFromMessageID(messageID message.ID, timestamp *time.Time, round *rounds.Round, pinned, hidden *bool, - status *channels.SentStatus) uint64 { - parentErr := errors.New("failed to UpdateFromMessageID") + status *channels.SentStatus) (uint64, error) { + parentErr := "failed to UpdateFromMessageID" // FIXME: this is a bit of race condition without the mux. // This should be done via the transactions (i.e., make a @@ -304,19 +311,19 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, currentMsgObj, err := impl.GetIndex(w.db, messageStoreName, messageStoreMessageIndex, impl.EncodeBytes(messageID.Marshal())) if err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Failed to get message by index: %+v", err)) - return 0 + if strings.Contains(err.Error(), impl.ErrDoesNotExist) { + return 0, errors.WithMessage(channels.NoMessageErr, parentErr) + } + return 0, errors.WithMessage(err, parentErr) } currentMsg := utils.JsToJson(currentMsgObj) uuid, err := w.updateMessage(currentMsg, &messageID, timestamp, round, pinned, hidden, status) if err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to updateMessage: %+v", err)) + return 0, errors.WithMessage(err, parentErr) } - return uuid + return uuid, nil } // updateMessage is a helper for updating a stored message. diff --git a/indexedDb/worker/channels/implementation.go b/indexedDb/worker/channels/implementation.go index 4d51b97e6a2941e07849c0e2e405539ccc86a8f7..9639bc185095e74cbf4b3e63256fead39bbcef82 100644 --- a/indexedDb/worker/channels/implementation.go +++ b/indexedDb/worker/channels/implementation.go @@ -263,9 +263,12 @@ type MessageUpdateInfo struct { // messageID, timestamp, round, pinned, and hidden are all nillable and may be // updated based upon the UUID at a later date. If a nil value is passed, then // make no update. +// +// Returns an error if the message cannot be updated. It must return +// [channels.NoMessageErr] if the message does not exist. func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, timestamp *time.Time, round *rounds.Round, pinned, hidden *bool, - status *channels.SentStatus) { + status *channels.SentStatus) error { msg := MessageUpdateInfo{UUID: uuid} if messageID != nil { msg.MessageID = *messageID @@ -294,12 +297,33 @@ func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, data, err := json.Marshal(msg) if err != nil { - jww.ERROR.Printf( - "[CH] Could not JSON marshal payload for UpdateFromUUID: %+v", err) - return + return errors.Errorf( + "could not JSON marshal payload for UpdateFromUUID: %+v", err) } - w.wm.SendMessage(UpdateFromUUIDTag, data, nil) + errChan := make(chan error) + w.wm.SendMessage(UpdateFromUUIDTag, data, func(data []byte) { + if data != nil { + errChan <- errors.New(string(data)) + } else { + errChan <- nil + } + }) + + select { + case err = <-errChan: + return err + case <-time.After(worker.ResponseTimeout): + return errors.Errorf("timed out after %s waiting for response from "+ + "the worker about UpdateFromUUID", worker.ResponseTimeout) + } +} + +// UuidError is JSON marshalled and sent to the worker for +// [wasmModel.UpdateFromMessageID]. +type UuidError struct { + UUID uint64 `json:"uuid"` + Error []byte `json:"error"` } // UpdateFromMessageID is called whenever a message with the message ID is @@ -313,7 +337,7 @@ func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, // no update. func (w *wasmModel) UpdateFromMessageID(messageID message.ID, timestamp *time.Time, round *rounds.Round, pinned, hidden *bool, - status *channels.SentStatus) uint64 { + status *channels.SentStatus) (uint64, error) { msg := MessageUpdateInfo{MessageID: messageID, MessageIDSet: true} if timestamp != nil { @@ -339,33 +363,34 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, data, err := json.Marshal(msg) if err != nil { - jww.ERROR.Printf("[CH] Could not JSON marshal payload for "+ + return 0, errors.Errorf("could not JSON marshal payload for "+ "UpdateFromMessageID: %+v", err) - return 0 } uuidChan := make(chan uint64) + errChan := make(chan error) w.wm.SendMessage(UpdateFromMessageIDTag, data, func(data []byte) { - var uuid uint64 - err = json.Unmarshal(data, &uuid) - if err != nil { - jww.ERROR.Printf("[CH] Could not JSON unmarshal response to "+ - "UpdateFromMessageID: %+v", err) - uuidChan <- 0 + var ue UuidError + if err = json.Unmarshal(data, &ue); err != nil { + errChan <- errors.Errorf("could not JSON unmarshal response "+ + "to UpdateFromMessageID: %+v", err) + } else if ue.Error != nil { + errChan <- errors.New(string(ue.Error)) + } else { + uuidChan <- ue.UUID } - uuidChan <- uuid }) select { case uuid := <-uuidChan: - return uuid + return uuid, nil + case err = <-errChan: + return 0, err case <-time.After(worker.ResponseTimeout): - jww.ERROR.Printf("[CH] Timed out after %s waiting for response from "+ + return 0, errors.Errorf("timed out after %s waiting for response from "+ "the worker about UpdateFromMessageID", worker.ResponseTimeout) } - - return 0 } // GetMessageMessage is JSON marshalled and sent to the worker for