-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Stack overflow in Subscriber.js #3229
Comments
🤔 this looks bit odd, it seems like we're keep trying to create safeSubscriber internally. as an immediate workaround, you can pass observer directly
and stack won't blow up. I may need dig what's happening internally still. |
@kwonoj const watch = (observer) => {
const sub = obs$.subscribe(observer);
return () => sub.unsubscribe();
}; i.e. if observer is not split into its respective functions. Doubly odd :) |
Looking at Subscriber.js, is |
The problem is that unbound methods are passed to const watch = (observer) => {
const sub = obs$.subscribe(
observer.next.bind(observer),
observer.error.bind(observer),
observer.complete.bind(observer));
return () => sub.unsubscribe();
};
|
Wow! Why wasn't Does it worth to change code, so that instead of stack overflow error, there is something else, due to |
@3n-mb The problem is that passing an unbound When the unbound If you look at the implementation of fn.call(this._context, value);
That means the call to In short, there is nothing to be fixed in RxJS. |
I see no reason to do let context: any = undefined; // instead of this on this line of Subscriber.ts. Unless there is something else outside of Can you try run tests with this change? I can't PR on a tag 5.5.6. |
@3n-mb Maybe. I know a little about the subscribe/subscription mechanisms in RxJS - I've poked around in those parts when building tools - but I sure don't know everything. Others will know more than me. Whether or not Seeing no reason not to change something is not quite the same as having a compelling reason for something to be changed. What's the upside of the change? A slightly better error message? I'm not sure how often the error would occur anyway, as it's usually the case that the observer itself is passed. Although, it seems it has been raised before: a quick search of the repo found an identical issue. Anyway, if you are keen to put in the effort to verify that the change is appropriate and has no ill effects and to convince the maintainers of such, you should make the PR against |
Observing functions (callbacks) are given to `.subscribe(next, error, complete)` by an outside code. But `rxjs` dictates a context of execution, instead of leaving it `undefined`. It sort of disrespects separation between callbacks that come from outside, and its own internals on the public API of the library. As a result, there are issues ReactiveX#3229, ReactiveX#1981, ReactiveX#1949, ReactiveX#2140, that happen due to `rxjs` mangling with execution context. Library behaves in an unexpected way. This change fixes an unsanctioned introduction of context to callback. Now, it is possible, that this weird behaviour was introduced to help some other parts of the lib. Tests should show this. And may be those places should change instead of keeping users of the library puzzled.
@cartant yes, there are now four issues! I mentioned all of them in a PR. Here is a view on this problem:
I have a huge problem with (3). And judging by the number of issues, I am not alone. Cause library behaves unexpectedly, unless, of cause, documentation says that given callbacks will be executed in some context (RTFM excuse 😄 ). |
The original example in here doesn't make any sense. I mean, I can follow it, but I have no idea what the intention is, and it makes it hard to see the problem. What is it that you want to do, @3n-mb, in the simplest possible example? |
The short reason for this code is in the comment: // want to wrap subscription into a function (library's external api)
const watch = (observer) => { ... } Let me unpack why library's external api needs In 3NWeb effort we make an electron app that has a core (electron's main process) and other apps on top (articulated as electron's renderer processes in beautiful windows). When I was making a test for RPC functionality, I created a mock, implemented with rxjs (I love this lib, thak you, guys). And I got an eye-popping, totally unexpected error about stack overflow. Something like |
Anyhow, the problem is that you're losing the context of the observer's functions when you pass them in as standalone functions. The context is actually assigned to the SafeSubscriber that "owns" those handlers and the subscription. This was actually done by design and we can't change it, at least right now. Since the problem is solved by binding your observer's handlers to the original observer (as suggested above), I'm going to close this issue. |
RxJS version: 5.5.6 (used in node)
Code to reproduce:
Expected behavior: complete without an error, and print 5
Actual behavior: line
subj.next(5);
overflows the stack, throwing the following error:Additional information:
watch
is creating a function call loop. Yet, it seems that a combination ofwatch
and a subscription via creating a new observernew Observer(...)
establishes a loop that throws up.Let me know if code for
watch
function violates rxjs' api. And if not, this is a bug.The text was updated successfully, but these errors were encountered: