Browse Source

handle x-spread saferEval

Hugo Di Francesco 4 years ago
parent
commit
54d9014dfe
3 changed files with 17 additions and 1 deletions
  1. 1 0
      examples/index.html
  2. 2 1
      src/utils.js
  3. 14 0
      test/error.spec.js

+ 1 - 0
examples/index.html

@@ -52,6 +52,7 @@
                     <td>
                         <div x-data="some.bad.expression()">I'm a broken component</div>
                         <button x-data x-on:click="something()">I break on click</button>
+                        <div x-data x-spread="not.good">Broken x-spread</div>
                     </td>
                 </tr>
 

+ 2 - 1
src/utils.js

@@ -138,7 +138,8 @@ export function getXAttrs(el, component, type) {
     let spreadDirective = directives.filter(directive => directive.type === 'spread')[0]
 
     if (spreadDirective) {
-        let spreadObject = saferEval(spreadDirective.expression, component.$data)
+        const { expression } = spreadDirective
+        let spreadObject = tryCatch(() => saferEval(expression, component.$data), { expression, el })
 
         // Add x-spread directives to the pile of existing directives.
         directives = directives.concat(Object.entries(spreadObject).map(([name, value]) => parseHtmlAttribute({ name, value })))

+ 14 - 0
test/error.spec.js

@@ -42,6 +42,20 @@ test('error in x-init eval contains element, expression and original error', asy
     )
 })
 
+test('error in x-spread eval contains element, expression and original error', async () => {
+    document.body.innerHTML = `
+        <div x-data x-spread="foo.bar">
+        </div>
+    `
+    // swallow the rendering error
+    await expect(Alpine.start()).rejects.toThrow()
+    expect(mockConsoleError).toHaveBeenCalledWith(
+        "Alpine: error in expression \"foo.bar\" in component:",
+        document.querySelector('[x-data]'),
+        "due to \"ReferenceError: foo is not defined\""
+    )
+})
+
 test('error in x-bind eval contains element, expression and original error', async () => {
     document.body.innerHTML = `
         <div x-data="{ foo: null }">