[Bug] Wrapping args in a Proxy throws an unintended assertion
- Dominant language
- TypeScript
- Stars
- 22.6k
- Forks
- 4.2k
- Avg merge
- 3d 12h
- Merged PRs (30d)
- 15
Description
### 🐞 Describe the Bug
If you wrap the `args` proxy in another proxy and try to get an undefined property, Ember throws an assertion.
```
Error: Assertion Failed: args proxies do not have real property descriptors, so you should never need to call getOwnPropertyDescriptor yourself. This code exists for enumerability, such as in for-in loops and Object.keys()
```
### 🔬 Minimal Reproduction
The repro app will display errors in the console.
https://github.com/sandydoo/ember-repro-args-proxy
```js
let argsProxy = new Proxy(
this.args,
{
get() {
// Doesn't even matter what you do here.
// You could return a static value and it will still error out .
return Reflect.get(...arguments);
}
}
);
// If args = { definedProp: true }
argsProxy.definedProp // => Returns `true`
argsProxy.undefinedProp // => Throws assertion
```
### 😕 Actual Behavior
It seems that, as part of its implementation, `Proxy` calls `getOwnPropertyDescriptor` on the target object. I don't have control over this 🤷♂️. In the case of `args`, `getOwnPropertyDescriptor` throws an error if you try to call it for an undefined prop. The purpose of the assertion seems to be to deter people from using `getOwnPropertyDescriptor` altogether, but since it's necessary for enumeration, it can only throw an error for undefined props.
https://github.com/emberjs/ember.js/blob/e6c38ecbbc1162e600e2058b8fa3bc93993e13aa/packages/%40ember/-internals/glimmer/lib/component-managers/custom.ts#L220-L224
### 🤔 Expected Behavior
I should be able to transparently access properties on `this.args` even via a Proxy.
### 🌍 Environment
- Ember: 3.21.1
- OS: MacOS
- Browser: Firefox, Chrome, and Safari
### 🧠 Thoughts
The assertion strikes me as a bit problematic for a few reasons:
1. It doesn't account for the native behaviour of `Proxy`.
2. Since you can't tell who the callee is and the function is actually necessary in some cases, the assertion is thrown inconsistently. For example, I can call `getOwnPropertyDescriptor` for any _defined_ prop without issues. I'm not sure of what use that would be though...
I would appreciate some feedback on this issue. Are proxies a no-go with args or can we live with the possibility of people calling `getOwnPropertyDescriptor`?
Contributor guide
Assessment
This issue has not been assessed yet.