Skip to content

Commit

Permalink
handle errors thrown by directive hooks (#5314) (#5324)
Browse files Browse the repository at this point in the history
* handle errors thrown by directive hooks

* fix import
  • Loading branch information
javoski authored and yyx990803 committed Apr 3, 2017
1 parent 255b627 commit 3c02655
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
8 changes: 6 additions & 2 deletions src/core/vdom/modules/directives.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* @flow */

import { emptyNode } from 'core/vdom/patch'
import { resolveAsset } from 'core/util/options'
import { resolveAsset, handleError } from 'core/util/index'
import { mergeVNodeHook } from 'core/vdom/helpers/index'

export default {
Expand Down Expand Up @@ -107,6 +107,10 @@ function getRawDirName (dir: VNodeDirective): string {
function callHook (dir, hook, vnode, oldVnode, isDestroy) {
const fn = dir.def && dir.def[hook]
if (fn) {
fn(vnode.elm, dir, vnode, oldVnode, isDestroy)
try {
fn(vnode.elm, dir, vnode, oldVnode, isDestroy)
} catch (e) {
handleError(e, vnode.context, `directive ${dir.name} ${hook} hook`)
}
}
}
25 changes: 22 additions & 3 deletions test/unit/features/error-handling.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ describe('Error handling', () => {
['render', 'render function'],
['beforeCreate', 'beforeCreate hook'],
['created', 'created hook'],
['beforeMount', 'beforeMount hook']
['beforeMount', 'beforeMount hook'],
['directive bind', 'directive foo bind hook']
].forEach(([type, description]) => {
it(`should recover from errors in ${type}`, done => {
const vm = createTestInstance(components[type])
Expand All @@ -32,7 +33,8 @@ describe('Error handling', () => {
// error in beforeUpdate/updated should affect neither child nor parent
;[
['beforeUpdate', 'beforeUpdate hook'],
['updated', 'updated hook']
['updated', 'updated hook'],
['directive update', 'directive foo update hook']
].forEach(([type, description]) => {
it(`should recover from errors in ${type} hook`, done => {
const vm = createTestInstance(components[type])
Expand All @@ -45,7 +47,8 @@ describe('Error handling', () => {

;[
['beforeDestroy', 'beforeDestroy hook'],
['destroyed', 'destroyed hook']
['destroyed', 'destroyed hook'],
['directive unbind', 'directive foo unbind hook']
].forEach(([type, description]) => {
it(`should recover from errors in ${type} hook`, done => {
const vm = createTestInstance(components[type])
Expand Down Expand Up @@ -173,6 +176,22 @@ function createErrorTestComponents () {
}
})

// directive hooks errors
;['bind', 'update', 'unbind'].forEach(hook => {
const key = 'directive ' + hook
const dirComp = components[key] = {
props: ['n'],
template: `<div v-foo="n">{{ n }}</div>`
}
const dirFoo = {}
dirFoo[hook] = function () {
throw new Error(key)
}
dirComp.directives = {
foo: dirFoo
}
})

// user watcher
components.userWatcherGetter = {
props: ['n'],
Expand Down

0 comments on commit 3c02655

Please sign in to comment.