Trie.prototype._updateNode(); TypeError: Cannot read property 'pop' of undefined
Ryanmtate opened this issue · comments
_updateNode is receiving undefined stack
Receiving TypeError: Cannot read property 'pop' of undefined
patricia-tree/baseTrie.js:359
var lastNode = stack.pop()
^
TypeError: Cannot read property 'pop' of undefined
Suspect WalkController is not passing stack in the callback of processNode();
Trie.prototype._findPath = function (targetKey, cb) {
var self = this
var root = self.root
var stack = []
targetKey = TrieNode.stringToNibbles(targetKey)
this._walkTrie(root, processNode, cb)
function processNode (root, node, keyProgress, walkController) {
var nodeKey = node.key || []
var keyRemainder = targetKey.slice(matchingNibbleLength(keyProgress, targetKey))
var matchingLen = matchingNibbleLength(keyRemainder, nodeKey)
stack.push(node)
if (node.type === 'branch') {
if (keyRemainder.length === 0) {
walkController.return(null, node, [], stack)
// we exhausted the key without finding a node
} else {
var branchIndex = keyRemainder[0]
var branchNode = node.getValue(branchIndex)
if (!branchNode) {
// there are no more nodes to find and we didn't find the key
walkController.return(null, null, keyRemainder, stack)
} else {
// node found, continuing search
walkController.only(branchIndex)
}
}
} else if (node.type === 'leaf') {
if (doKeysMatch(keyRemainder, nodeKey)) {
// keys match, return node with empty key
walkController.return(null, node, [], stack)
} else {
// reached leaf but keys dont match
walkController.return(null, null, keyRemainder, stack)
}
} else if (node.type === 'extention') {
if (matchingLen !== nodeKey.length) {
// keys dont match, fail
walkController.return(null, null, keyRemainder, stack)
} else {
// keys match, continue search
walkController.next()
}
}
}
}
@Ryanmtate do you have the code that generates this error?
I've seen this a bunch with the TestRPC. Was too intermittent to figure out the root cause however.
This problem still exists with TestRPC, I've spent a few hours trying to track down how to fix it, but so far haven't figured out how. Callback hell...
I've tried making it pass an error in the callback from watchController.only
in walkTrie
helper processNode
but there seems to be a lot of code elsewhere that doesn't follow the callback(error, value) convention, causing all kinds of strange behaviour. I squashed many of those, but I don't think calling the continuation in only
with an error if node
is undefined is the right fix. It seems to put the server's state manager in a broken state, all subsequent calls return the same error. Don't fully understand all the surrounding code yet.
Giving up for now, might look at it again later if I have time. But I'm documenting my findings below if anyone else has the patience:
The symptoms start with this line in Trie._findPath
's processNode
walkController.only(branchIndex)
which then runs this function
only: function (childIndex) {
var childRoot = node.getValue(childIndex)
self._lookupNode(childRoot, function (node) { // node is undefined here
var childKey = key.slice()
childKey.push(childIndex)
processNode(childRoot, node, childKey, cb)
})
}
In the recursive call for processNode from above it calls this line
if (!node) return cb() <-- no arguments
this is cb from above
if (err) {
return onDone(err)
}
// returnValues is an empty array from the walkTrie closure, so essentially onDone()
onDone.apply(null, returnValues)
onDone from above is the callback in Trie.put
at this line
self._findPath(key, function (err, foundValue, keyRemainder, stack) {
// all arguments here are undefined because it gets called with no arguments
if (err) {
return cb(err);
}
// then update
// this call crashes the program because stack is undefined
self._updateNode(key, value, keyRemainder, stack, cb)
})
Will cautiously close this since the issue is pretty old, there hasn't been any reports lately and the code base changed significantly since. There has also been a refactor of the WalkController
in #135 by @jochem-brouwer. Feel free to reopen though if you still think this is an issue.