-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Issue with mergeMixins
when accessing a service in a getter
#18860
Comments
@nlfurniss and I spent some time today debugging this and identified the root cause of this bug. While recursing through mixins in ember.js/packages/@ember/-internals/metal/lib/mixin.ts Lines 304 to 311 in 55ffe63
However, this only works as designed if the type is a classic CP or observer or a plain value, not when it is a getter. This is because the simple assignment used here— let prev = (values[key] = base[key]); —by definition must evaluate I emphasize “as designed” above because in many cases, it still happens to work… but if the getter in question happens to call a service injection and that happens during initialization such that the class in question hasn’t yet been associated with an owner, then the bug reported here appears. Calling the getter like this invokes it, which triggers the entire process of resolving an injection, which in turn drops down through to Evaluating the getter is not the intended behavior here at all, though. Instead of being evaluated, a getter needs to be "copied over", just as with CPs/observers/other items. (This particular code path is only a few years old, but from what I can tell from spelunking, I don’t think we ever handled this case quite correctly, unless perhaps by accident!) I suspect the solution will involve doing something roughly like this: if (desc === undefined) {
let baseObjDesc = Object.getOwnPropertyDescriptors(base);
let nativeDesc = typeof baseObjDesc[key];
if (nativeDesc?.get === 'function') {
Object.defineProperty(values, key, nativeDesc);
} else {
let prev = (values[key] = base[key]);
if (typeof prev === 'function') {
updateObserversAndListeners(base, key, prev, false);
}
}
} Additional considerations:
|
@rwjblue and I poked at this this morning and my basic read was correct. (PHEW) I'm working on getting a failing test up, hopefully by EOD today, and then will try to get up a PR which fixes this and maybe also improves the perf of this path if possible. Notably, we try to do the right thing here… but it only handles the cases where we have an actual |
Additional debugging with @rwjblue after trying and failing to get a simple test case in place showed why this has been rare and helped us ID the root of the issue. Our handling of getters and setters works correctly for cases where we have only classic classes, or only native classes, or native classes extending classic classes. In some cases, however, it fails when we have "zebra-striping" of class types, with a classic class extending a native class which extends a (stack of) classic class(es). We correctly handle native getters in mixin and POJOs passed to |
@chriskrycho I'm not sure it's the same issue (as I mentioned above) but there is something like a test case in the other issue. You can perhaps also use that. |
Recently found an issue with mergeMixins. it affects Ember versions at least as far back as 3.12 and also current release and LTS.
As I understand it, the issue is when a mixin defines a property (doesn’t necessarily have a value) then we try to access the value during construction before owner is set. This breaks getters that access services. Shared findings with @pzuraq.
Error message:
Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container. Error: Assertion Failed: Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container.
Code where issue arrises
(Please note: the original link was to
master
😞. I've changed the tag to the version of ember published the day before, but I have no memory of the original code it linked to)Reproduction (Gist)
The text was updated successfully, but these errors were encountered: