[ember-source 3.13] Infinite loop causes stack overflow
patocallaghan opened this issue · comments
Environment
- Ember Version: 3.13.0-beta.5
- Ember CLI Version: 3.6.1
- Ember CP Validations Version:
master
- Reproduction PR: #660
While preparing our app to be Ember 3.13-ready we've come across a number of infinite loops which cause our app to crash. I'm not exactly sure what the problem is but I think it has to do with the recent @tracked
internal changes which are shipping with 3.13. The failing tests I've created in #660 here are passing in 3.12.0 but start failing when I bump to 3.13.0-beta.1.
Steps to Reproduce
I have a component called <MyComponent />
. It has a computed property which is based on cheese
which can be passed in and some validations on a passed in model, model.validations.isValid
. The validations are nothing special and in my reproduction case are just using what where being used for tests in the ember-cp-validations repo.
import Component from '@ember/component';
import { and } from '@ember/object/computed';
export default Component.extend({
myProp: and('cheese', 'model.validations.isValid')
});
If cheese
is undefined
it seems to cause an infinite loop in the model.validations.isValid
part of the computed property.
Uncaught (in promise) RangeError: Maximum call stack size exceeded
at setupMandatorySetter (index.js:753)
at tagForProperty (index.js:239)
at ComputedProperty.get (index.js:3302)
at Class.CPGETTER_FUNCTION [as username] (index.js:2639)
at getPossibleMandatoryProxyValue (index.js:1764)
at get (index.js:1837)
at _getPath (index.js:1871)
at Object.get (index.js:1821)
at factory.js:489
at Array.map (<anonymous>)
console.log
-ing what is output on the _getPath
line shows that it seems to be stuck in some sort of loop trying to retrieve the validation for the username
, before it throws a stack overflow
Strangely, doing a few things here cause the infinite loop not to occur and the test to pass fine.
- Changing the template to call
this.model.validations
orthis.model.validations.isValid
first beforethis.myProp
. Callingthis.model
doesn't resolve the infinite loop. Moving thethis.model....
call AFTERthis.myProp
also doesn't solve the infinite loop.
- Changing the order of the
and
computed property resolves the infinite loop. Having theundefined
cheese
property second solves the problem.
myProp: and('model.validations.isValid', 'cheese')
While I reproduced this problem in tests it can also be seen in a running app. In my PR for demo purposes I've just added the following code to the index.hbs
This also results in an infinite loop and stack overflow which breaks rendering but with what looks like a different path than the test
index.js:613 Uncaught (in promise) RangeError: Maximum call stack size exceeded
at WeakMap.get (<anonymous>)
at getName (index.js:613)
at Function.classToString [as toString] (index.js:4158)
at Class.toString (core_object.js:546)
at Class.<anonymous> (factory.js:488)
at index.js:3320
at untrack (index.js:1742)
at ComputedProperty.get (index.js:3319)
at Class.CPGETTER_FUNCTION [as __ATTRS_RESULT_COLLECTION__] (index.js:2639)
at getPossibleMandatoryProxyValue (index.js:1764)
This should be fixed by emberjs/ember.js#18406
Fix has been released in https://github.com/emberjs/ember.js/releases/tag/v3.13.0