Subscribe on changes!

Strict mode, Safari 13. X, Reactive Proxy object with an array of proxies in it. This time, manipulating array length or push will cause an error

avatar
Jun 10th 2021

Version

3.0.11

Reproduction link

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuICA8aDE+PC9oMT5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQgc2V0dXA+XG4gIFwidXNlIHN0cmljdFwiO1xuICBmdW5jdGlvbiBoYW5kbGVyUHJveHkodGFyZ2V0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm94eSh0YXJnZXQsIHtcbiAgICAgIGdldCh0YXJnZXQsIHByb3BlcnR5LCByZWMpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2dldCcsIHByb3BlcnR5KVxuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wZXJ0eSwgcmVjKVxuICAgICAgfSxcbiAgICAgIHNldCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgcmVjKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdzZXQnLCBwcm9wZXJ0eSwgdmFsdWUpXG4gICAgICAgIHJldHVybiBSZWZsZWN0LnNldCh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSwgcmVjKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgaW1wb3J0IHsgcmVhY3RpdmUgfSBmcm9tICd2dWUnXG5cbiAgY29uc3QgdGVzdCA9IHJlYWN0aXZlKGhhbmRsZXJQcm94eSh7XG4gICAgY2hpbGRyZW46IGhhbmRsZXJQcm94eShbXSlcbiAgfSkpXG5cblx0dGVzdC5jaGlsZHJlbi5sZW5ndGggPSAwXG48L3NjcmlwdD4ifQ==

Steps to reproduce

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.11/vue.global.js"></script>
</head>
<body>
    <script>
        "use strict";
        function handlerProxy(target) {
            return new Proxy(target, {
                get(target, property, rec) {
                    console.log('get', property)
                    return Reflect.get(target, property, rec)
                },
                set(target, property, value, rec) {
                    console.log('set', property, value)
                    return Reflect.set(target, property, value, rec)
                }
            })
        }
        const { reactive } = Vue

        const test = reactive(handlerProxy({
            children: handlerProxy([])
        }))
        // TypeError: Proxy object's 'set' trap returned falsy value for property 'length'
        test.children.length = 0
        // TypeError: Attempted to assign to readonly property.
        test.children.push(1, 2, 3)
    </script>
</body>
</html>

What is expected?

Not an error

What is actually happening?

TypeError: Proxy object's 'set' trap returned falsy value for property 'length' or TypeError: Attempted to assign to readonly property.

avatar
Jun 10th 2021

It seems Safari's bug, It works fine at Safari 14.0.3 (macOS - 10.15.7)

avatar
Jun 10th 2021

It seems Safari's bug, It works fine at Safari 14.0.3 (macOS - 10.15.7)

14.X dont have a problem, 13. X has this problem, is there no way from the Vue except to upgrade Safari? I suspected it was a Proxy problem twice, but it turned out not to be the case. It only happens when reactive is used

avatar
Jun 11th 2021

This doesn't seem to be related to Vue as it can be reproduced without using reactive by omitting the return statement in the set trap