Closed egaoneko closed 4 years ago
The for loops i
's are block-scoped to the for loop
they are in so if the loops were nested then they would be affecting each other.
The index
was the forEach index, when changing to an ES1 for loop it referenced the index of the for loop which is defined as i
.
The this
was defined in the callback of the forEach
at the end }, cloneRouter.stack)
which sets the forEach
local this
to cloneRouter.stack
As for the heap memory issue, I wonder why the tests and manual checking didn't catch it. What was the code implementation like when you got this error? Maybe we can narrow down the culprit.
The only thing I think could be possibly causing some strange side effect is the function I madesetRouterParams()
to create a closure for that particular for loop
.
@niftylettuce any ideas?
Our test suites are failing with "JavaScript heap out of memory" after upgrading to 8.0.7 as well, just like egaoneko is experiencing. Practically the same stacktrace as above. Only difference is that I'm using node 13.8.0.
@JacobMGEvans
Oh, I miss watched about index
with forEach
.
When I tested it, It does not occured with just koa and router.
We use koa with Next.js, TypeScript, Webpack.
I try to make a sample code for it.
Our test suites are failing with "JavaScript heap out of memory" after upgrading to 8.0.7 as well, just like egaoneko is experiencing. Practically the same stacktrace as above. Only difference is that I'm using node 13.8.0.
@Gusten Would it be possible to see the tests that are failing from your code and unit it is testing?
Also what is the tech stack, @egaoneko mentioned that Next.js, TS and Webpack are being used in the project that this issue is occurring?
EDIT: Also, I am attempting to replicate the issue here https://codesandbox.io/s/koa-template-hv82k If anyone else can recreate the issue with this template please send me the link.
@JacobMGEvans I made a sample code causing infinite loops. https://codesandbox.io/s/koa-router-807-test-yj8c5
Router.prototype.use = function () {
...
for (var i = 0; i < middleware.length; i++) {
var m = middleware[i];
if (m.router) {
var cloneRouter = Object.assign(Object.create(Router.prototype), m.router, {
stack: m.router.stack.slice(0)
});
for (var i = 0; i < cloneRouter.stack.length; i++) {
var nestedLayer = cloneRouter.stack[i];
var cloneLayer = Object.assign(
Object.create(Layer.prototype),
nestedLayer
);
if (path) cloneLayer.setPrefix(path);
if (router.opts.prefix) cloneLayer.setPrefix(router.opts.prefix);
router.stack.push(cloneLayer);
cloneRouter.stack[i] = cloneLayer;
}
...
}
return this;
};
This problem occurs in the above code when middlewares are bigger than nested layers.
As I said before, this happens because of the nested i
.
Unlike let
andconst
, var
is a function scope, so this problem occurs.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
Router.prototype.use = function () {
...
for (var i = 0; i < middleware.length; i++) {
var m = middleware[i];
if (m.router) {
var cloneRouter = Object.assign(Object.create(Router.prototype), m.router, {
stack: m.router.stack.slice(0)
});
for (var i = 0; i < cloneRouter.stack.length; i++) {
var nestedLayer = cloneRouter.stack[i];
var cloneLayer = Object.assign(
Object.create(Layer.prototype),
nestedLayer
);
if (path) cloneLayer.setPrefix(path);
if (router.opts.prefix) cloneLayer.setPrefix(router.opts.prefix);
router.stack.push(cloneLayer);
cloneRouter.stack[i] = cloneLayer;
}
...
}
return this;
};
So I changed like the above code, it works.
v8.0.8 released
@egaoneko hahaha I can't believe I missed that nested for loop
nice catch and fix! đ
I'll see if I can write a test for this particular section of code. Thanks for fixing my mistake đ
v8.0.8 released
@niftylettuce I think you missed releasing it on npm thou!, Would be appreciated :)
It is released on npm.
https://www.npmjs.com/package/@koa/router v8.0.8
I forgot to release the legacy version of koa-router, but just did so.
node.js version: 10.16.0
npm/yarn and version: 1.17.3
@koa/router
version: 8.0.7koa
version: 2.11.0Error message:
Expected reason:
I tried to find the reason from the recent changes in PR(#50). I found some codes that expected bugs.
https://github.com/koajs/router/commit/e07397c43802c6c9b2064dd4994944b738cb3984#diff-504fd89f344be1e9c4b583f3ebd7428aL262
In this refactoring, there are three
i
are declared and effected themself. I think it occurs infinite loop.https://github.com/koajs/router/commit/e07397c43802c6c9b2064dd4994944b738cb3984#diff-504fd89f344be1e9c4b583f3ebd7428aR283
Before refactoring, In this section(
this[index] = cloneLayer
) refered toindex
. But after refatoring it chaged likecloneRouter.stack[i] = cloneLayer
.I wonder where the
index
has been referenced and why I changed it toi
.cc. @JacobMGEvans