Reputation: 2202
The following code, I cannot find any problem out, but yet, it sometimes output "'i' should not be higher than handlers.length".
function callNext(req, res, handlers, cb) {
let i = -1;
let next = (thisObj) => {
i += 1;
if (i == handlers.length) {
return cb();
} else if (i > handlers.length) {
console.log("'i' should not be higher than handlers.length.");
console.log(handlers.length, i); // => 9 10
return;
}
try {
return handlers[i].call(thisObj || this, req, res, next);
} catch (e) {
this.onerror(e, req, res);
}
};
return next();
}
Because based on human logic, the function is returned when i
is equal to handlers.length
, and the code below should never run, this problem really drives me nut.
Upvotes: 1
Views: 53
Reputation: 18378
It happens because i
will increment on the next call after if (i == handlers.length) return cb();
and become handlers.length + 1
You have to do
if (i >= handlers.length) {
return cb();
}
or something like this.
Upvotes: 0
Reputation: 3845
The easiest assumption is that some of the handlers wrongly call next
twice.
Generally i would recommend to safeguard again this anyways, you could use something like
function callNext(req, res, handlers, cb) {
let lastCalledIndex;
let next = (thisObj, index) => {
if (index === lastCalledIndex) {
console.log("'next' called multiple times from handler");
return;
}
lastCalledIndex = index;
if (i === handlers.length) {
return cb();
} else if (index > handlers.length) {
console.log("'index' should not be higher than handlers.length.");
console.log(handlers.length, index); // => 9 10
return;
}
try {
return handlers[index].call(thisObj || this, req, res, next.bind(undefined, thisObj, index + 1));
} catch (e) {
this.onerror(e, req, res);
}
};
return next(this, 0);
}
Upvotes: 1