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