0
function createWallet(network, walletToken, deviceToken) {
return new Promise((resolve, reject) => {

    findWalletByWalletToken(network, walletToken)
    .then((docs) => {
        if (docs.length !== 0) {    
            for (var i in docs) {
                if (docs[i].curDeviceToken == deviceToken || docs[i].walletToken.indexOf(walletToken) !== -1){
                    reject(new Error("walletToken already exists"));
                    return
                }
            }

        }
        console.log(docs)
    })
    .catch((err) => {
        console.log(err);
    })

    findDeviceByDeviceToken(network, deviceToken)
    .then((docs) => {
        resolve(docs);
    })
})
.then((docs) => {
          // Adds a wallet
     }

The log looks like this

Docs in WalletTokenSearch[object Object],[object Object]
Docs in WalletTokenSearch[object Object],[object Object]
Docs in WalletTokenSearch[object Object],[object Object]
Docs in WalletTokenSearch[object Object],[object Object]
Docs in WalletTokenSearch[object Object],[object Object]
Docs in WalletTokenSearch[object Object],[object Object]
Docs in WalletTokenSearch[object Object],[object Object]
[Hail][DB] Inserted new wallet
Docs in WalletTokenSearch[object Object],[object Object]

The Docs in WalletTokenSearch[object Object],[object Object] is a print statement in findWalletByWalletToken

The problem is that I’ll hit the endpoint multiple times and every now and then the same input will pass through the code and get added to the db creating a duplicate… You could do this over and over again and add thousands of duplicates this way

arshbot
  • 12,535
  • 14
  • 48
  • 71
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Oct 21 '17 at 22:53
  • do you understand that `findWalletByWalletToken` and `findDeviceByDeviceToken` are essentially running concurrently? – Jaromanda X Oct 21 '17 at 22:56

1 Answers1

2

You are always calling both findWalletByWalletToken and findDeviceByDeviceToken, no matter what. Your promise is fulfilled if the latter finishes first, or when the former doesn't reject the promise. This is a race condition at its finest.

Notice that both actions are executed, regardless of their result. I don't think that's what you want.

function createWallet(network, walletToken, deviceToken) {
    return findWalletByWalletToken(network, walletToken).then(docs => {
        for (var i=0; i<docs.length; i++) {
            if (docs[i].curDeviceToken == deviceToken || docs[i].walletToken.indexOf(walletToken) !== -1){
                throw new Error("walletToken already exists");
            }
        }
        console.log(docs)
        // only call this here:
        return findDeviceByDeviceToken(network, deviceToken);
    }).then((docs) => {
        // Adds a wallet
    });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375