-
Notifications
You must be signed in to change notification settings - Fork 29.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Active Domain
context is being leaked between server requests.
#26081
Comments
Hi @m0uneer. Is this a regression from previous versions of node? The domains module has a lot of edge cases and is deprecated. I would recommend using async_hooks API instead. There are some userspace modules (e.g. cls-hooked) that provide a user-friendly API on top of async-hooks. |
This seems like it could be the server counterpart of #25456. Basically, it seems likely that in the repro above, the parser of the first HTTP request is reused from one request to the next but its domain is not reset/re-attached after the first request. I would think a fix similar to what's been done in #25459 for HTTP clients could fix this issue. |
Actually, scratch what I mentioned above. It looks like the issue is related to the implementation of promises that you use in that repo. It seems that implementation doesn't exit from the domain it entered when it throws an error? For instance, exiting the current domain with I'm not sure if that would be the right fix for your use case or if it'd be possible to exit the current domain in your promises implementation for a more general solution. In other words. so far this doesn't look like a bug in node but I may be missing something. |
Thanks for your responses @misterdjules . But I wonder, why the bug occurs with POST requests only? |
@m0uneer I'm able to reproduce the problem you described by sending GET requests. |
@misterdjules , @ofrobots , the original code is written in TS and built for ES5. I copied pasted the compiled code and edited it to make the repo as simple as possible and this explains why the I tried the |
I think your problem essentially boils down to this:
Every time a function is bound to a domain, if that function throws and the thrown error is caught, the domain that was bound to this function won't be exited. When running the promise executor in your promises implementation as bound to the domain, that domain is never exited when the promise's executor throw, so it's left on the stack even after that http handler completes its execution. |
@misterdjules exactly! Now it makes sense why in my case __awaiter(this, void 0, void 0, function* () {
try {
var p1 = new Promise(() => {
throw new Error('test');
});
yield new Promise(() => {
throw new Error('test');
});
}
catch (err) {
// Two call are needed to fix the problem.
process.domain.exit();
process.domain.exit();
next(err);
}
}); Well, I'm looking now for a fix to my Promise patch and I will let you know when I succeeded. |
@m0uneer Does it sound reasonable then if we close this issue as it doesn't seem to be a bug with domains? We can still discuss it here though if we close it :) |
@misterdjules I tried to find a solution that fits my application but all solutions lead to destroying the context that I use later in the code. So, I ended up looping on the domain._stack.forEach(stackedDomain => stackedDomain.exit()); Do you think there is any better solution? |
Version: v6.14.3 and v10.5.0
Express Version: 4.16.4
Platform:
Linux m-pc 4.13.0-41-generic # 46~16.04.1-Ubuntu SMP Thu May 3 10:06:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Steps (Generating a simple Express app):
$ npm install express-generator -g
$ express --view=pug myapp
$ npm i
domain
implementations.$ npm start
/
.Expected:
Always return
Error('test')
.Actual:
Only first request returns
Error('test')
and all the comming requests returnError('Context Leaked!')
A link to a repo to reproduce:
https://github.com/m0uneer/domain-promise-problem
The text was updated successfully, but these errors were encountered: