Skip to content
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

[BUGFIX beta] Fix issue with Ember.trySet on destroyed objects. #13355

Merged
merged 1 commit into from
Feb 15, 2018

Conversation

rwjblue
Copy link
Member

@rwjblue rwjblue commented Apr 18, 2016

Ember.trySet is designed to be an error-tolerant form of Ember.set (per its public API documentation). However, in some circumstances an error is still thrown when setting on a destroyed object.

Prior to this change, the following would properly prevent an error:

let obj = { some: { deep : 'path', isDestroyed: true }};

Ember.trySet(obj, 'some.deep', 'stuff');

But the following would throw an error incorrectly:

let obj = { some: 'path', isDestroyed: true };

Ember.trySet(obj, 'some', 'stuff');

This fixes the latter case...

Fixes #12356.

@rwjblue
Copy link
Member Author

rwjblue commented Apr 18, 2016

@krisselden / @stefanpenner - r?

@stefanpenner
Copy link
Member

Looks ok, but now that if conditional won't be stripped

@rwjblue
Copy link
Member Author

rwjblue commented Apr 18, 2016

@stefanpenner - Yep, (a similar if is also present in setPath below this). If I embed the check into the assertion itself (which is possible) then we would actually do a set on a destroyed object when in production (because there is nothing left in the code to do a short-circuit). Is that better?

@stefanpenner
Copy link
Member

Oops you are correct. This looks good to me

@rwjblue
Copy link
Member Author

rwjblue commented Apr 18, 2016

@krisselden - Any objections?

@rwjblue
Copy link
Member Author

rwjblue commented Apr 19, 2016

I'm going to assign to @krisselden for review. I want to make sure that we are all happy/ok with this...

@krisselden
Copy link
Contributor

I'm ok with this, though, isDestroyed isn't really an ember-metal concept, we should have a value we set meta to, to mean it is destroyed.

Maybe then we could fix the long standing issue of recreating meta() on a destroyed object.
/cc @stefanpenner

@rwjblue
Copy link
Member Author

rwjblue commented May 4, 2016

@krisselden - Would you prefer that to happen in this PR or can it happen subsequently?

@krisselden
Copy link
Contributor

It can be after, I'm sure enforcing not recreating meta will expose some bugs

@krisselden
Copy link
Contributor

Please though open a tracking issue, I keep forgetting about. I think our teardown sometimes recreates the mets itself

@@ -62,8 +62,11 @@ export function set(obj, keyName, value, tolerant) {
return setPath(obj, keyName, value, tolerant);
}

assert(`calling set on destroyed object: ${toString(obj)}.${keyName} = ${toString(value)}`,
!obj.isDestroyed);
if (obj.isDestroyed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krisselden should we actually allow setting through destroyed objects or to the descs? My intuition leads me to believe this should actually occur before line 53.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically 3 scenarios exist.

  1. set on plain object property
  2. set on descriptor
  3. set on deep object

We currently guard/assert for 1, and I believe we must absolutely also guard/assert for 2. I also believe we should consider the same for 3, if others disagree I would like to be convinced.

@homu
Copy link
Contributor

homu commented May 17, 2016

☔ The latest upstream changes (presumably #13502) made this pull request unmergeable. Please resolve the merge conflicts.

@vvohra
Copy link

vvohra commented Apr 11, 2017

I was wondering about the status of this PR.

Looking at this twiddle and checking the console, it seems the issue is still valid on Ember 2.12.

@locks locks self-assigned this Apr 21, 2017
`Ember.trySet` is designed to be an error-tolerant form of `Ember.set`
(per its public API documentation). However, in some circumstances an
error is still thrown when setting on a destroyed object.

Prior to this change, the following would properly prevent an error:

```js
let obj = { some: { deep : 'path', isDestroyed: true }};

Ember.trySet(obj, 'some.deep', 'stuff');
```

But the following would throw an error incorrectly:

```js
let obj = { some: 'path', isDestroyed: true };

Ember.trySet(obj, 'some', 'stuff');
```

This fixes the latter case...
@mmun
Copy link
Member

mmun commented Feb 15, 2018

@rwjblue I've rebased this PR onto master.

@stefanpenner stefanpenner merged commit a7d5ed5 into emberjs:master Feb 15, 2018
@stefanpenner stefanpenner deleted the fix-trySet branch February 15, 2018 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ember.trySet() throws 'Assertion Failed: calling set on destroyed object'
7 participants