From d00a91b3efb15f6a35f9c28e3deb642d7706f8f1 Mon Sep 17 00:00:00 2001 From: Jake Taylor <jake@elixxir.io> Date: Mon, 19 Dec 2022 12:17:26 -0600 Subject: [PATCH] fix crashes --- indexedDb/dm/implementation.go | 85 ++++++++++++++++++++-------------- indexedDb/utils.go | 18 ++++--- 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/indexedDb/dm/implementation.go b/indexedDb/dm/implementation.go index 33279593..5f2361ac 100644 --- a/indexedDb/dm/implementation.go +++ b/indexedDb/dm/implementation.go @@ -19,6 +19,7 @@ import ( "gitlab.com/elixxir/xxdk-wasm/indexedDb" "gitlab.com/elixxir/xxdk-wasm/utils" "gitlab.com/xx_network/primitives/id" + "strings" "sync" "syscall/js" "time" @@ -99,14 +100,16 @@ func (w *wasmModel) Receive(messageID dm.MessageID, nickname string, text []byte var err error // If there is no extant Conversation, create one. - if result, err := indexedDb.Get(w.db, conversationStoreName, - utils.CopyBytesToJS(pubKey)); err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to get Conversation: %+v", err)) - return 0 - } else if len(result) == 0 { - err = w.joinConversation(nickname, pubKey, dmToken, codeset) - jww.ERROR.Printf("%+v", err) + if _, err := indexedDb.Get(w.db, conversationStoreName, utils.CopyBytesToJS(pubKey)); err != nil { + if strings.Contains(err.Error(), indexedDb.ErrDoesNotExist) { + err = w.joinConversation(nickname, pubKey, dmToken, codeset) + if err != nil { + jww.ERROR.Printf("%+v", err) + } + } else { + jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, + "Unable to get Conversation: %+v", err)) + } return 0 } else { jww.DEBUG.Printf("Conversation with %s already joined", nickname) @@ -139,14 +142,16 @@ func (w *wasmModel) ReceiveText(messageID dm.MessageID, nickname, text string, var err error // If there is no extant Conversation, create one. - if result, err := indexedDb.Get(w.db, conversationStoreName, - utils.CopyBytesToJS(pubKey)); err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to get Conversation: %+v", err)) - return 0 - } else if len(result) == 0 { - err = w.joinConversation(nickname, pubKey, dmToken, codeset) - jww.ERROR.Printf("%+v", err) + if _, err := indexedDb.Get(w.db, conversationStoreName, utils.CopyBytesToJS(pubKey)); err != nil { + if strings.Contains(err.Error(), indexedDb.ErrDoesNotExist) { + err = w.joinConversation(nickname, pubKey, dmToken, codeset) + if err != nil { + jww.ERROR.Printf("%+v", err) + } + } else { + jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, + "Unable to get Conversation: %+v", err)) + } return 0 } else { jww.DEBUG.Printf("Conversation with %s already joined", nickname) @@ -181,14 +186,16 @@ func (w *wasmModel) ReceiveReply(messageID dm.MessageID, reactionTo dm.MessageID var err error // If there is no extant Conversation, create one. - if result, err := indexedDb.Get(w.db, conversationStoreName, - utils.CopyBytesToJS(pubKey)); err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to get Conversation: %+v", err)) - return 0 - } else if len(result) == 0 { - err = w.joinConversation(nickname, pubKey, dmToken, codeset) - jww.ERROR.Printf("%+v", err) + if _, err := indexedDb.Get(w.db, conversationStoreName, utils.CopyBytesToJS(pubKey)); err != nil { + if strings.Contains(err.Error(), indexedDb.ErrDoesNotExist) { + err = w.joinConversation(nickname, pubKey, dmToken, codeset) + if err != nil { + jww.ERROR.Printf("%+v", err) + } + } else { + jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, + "Unable to get Conversation: %+v", err)) + } return 0 } else { jww.DEBUG.Printf("Conversation with %s already joined", nickname) @@ -223,14 +230,16 @@ func (w *wasmModel) ReceiveReaction(messageID dm.MessageID, reactionTo dm.Messag var err error // If there is no extant Conversation, create one. - if result, err := indexedDb.Get(w.db, conversationStoreName, - utils.CopyBytesToJS(pubKey)); err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Unable to get Conversation: %+v", err)) - return 0 - } else if len(result) == 0 { - err = w.joinConversation(nickname, pubKey, dmToken, codeset) - jww.ERROR.Printf("%+v", err) + if _, err := indexedDb.Get(w.db, conversationStoreName, utils.CopyBytesToJS(pubKey)); err != nil { + if strings.Contains(err.Error(), indexedDb.ErrDoesNotExist) { + err = w.joinConversation(nickname, pubKey, dmToken, codeset) + if err != nil { + jww.ERROR.Printf("%+v", err) + } + } else { + jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, + "Unable to get Conversation: %+v", err)) + } return 0 } else { jww.DEBUG.Printf("Conversation with %s already joined", nickname) @@ -258,8 +267,9 @@ func (w *wasmModel) ReceiveReaction(messageID dm.MessageID, reactionTo dm.Messag return uuid } -func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID dm.MessageID, - timestamp time.Time, round rounds.Round, status dm.Status) { +func (w *wasmModel) UpdateSentStatus(uuid uint64, + messageID dm.MessageID, timestamp time.Time, round rounds.Round, + status dm.Status) { parentErr := errors.New("failed to UpdateSentStatus") // FIXME: this is a bit of race condition without the mux. @@ -274,15 +284,20 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID dm.MessageID, // Use the key to get the existing Message currentMsg, err := indexedDb.Get(w.db, messageStoreName, key) if err != nil { + jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, + "Unable to get message: %+v", err)) return } // Extract the existing Message and update the Status newMessage := &Message{} - err = json.Unmarshal([]byte(currentMsg), newMessage) + err = json.Unmarshal([]byte(utils.JsToJson(currentMsg)), newMessage) if err != nil { + jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, + "Could not JSON unmarshal message: %+v", err)) return } + newMessage.Status = uint8(status) if !messageID.Equals(dm.MessageID{}) { newMessage.MessageID = messageID.Bytes() diff --git a/indexedDb/utils.go b/indexedDb/utils.go index 1aa6ff45..a8e7fd8e 100644 --- a/indexedDb/utils.go +++ b/indexedDb/utils.go @@ -22,9 +22,13 @@ import ( "time" ) -// dbTimeout is the global timeout for operations with the storage -// [context.Context]. -const dbTimeout = time.Second +const ( + // dbTimeout is the global timeout for operations with the storage + // [context.Context]. + dbTimeout = time.Second + // ErrDoesNotExist is an error string for got undefined on Get operations. + ErrDoesNotExist = "result is undefined" +) // NewContext builds a context for indexedDb operations. func NewContext() (context.Context, context.CancelFunc) { @@ -62,8 +66,8 @@ func Get(db *idb.Database, objectStoreName string, key js.Value) (js.Value, erro return js.Undefined(), errors.WithMessagef(parentErr, "Unable to get from ObjectStore: %+v", err) } else if resultObj.IsUndefined() { - return js.Undefined(), errors.WithMessage(parentErr, - "Unable to get from ObjectStore: result is undefined") + return js.Undefined(), errors.WithMessagef(parentErr, + "Unable to get from ObjectStore: %s", ErrDoesNotExist) } // Process result into string @@ -111,8 +115,8 @@ func GetIndex(db *idb.Database, objectStoreName string, return js.Undefined(), errors.WithMessagef(parentErr, "Unable to get from ObjectStore: %+v", err) } else if resultObj.IsUndefined() { - return js.Undefined(), errors.WithMessage(parentErr, - "Unable to get from ObjectStore: result is undefined") + return js.Undefined(), errors.WithMessagef(parentErr, + "Unable to get from ObjectStore: %s", ErrDoesNotExist) } // Process result into string -- GitLab