Skip to content

Commit 35638df

Browse files
committed
try/finally around directive cleanup
1 parent d2f2ffc commit 35638df

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

src/client/parts.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,11 @@ export function create_directive_part(node: Node): Part {
296296
return fn => {
297297
if (prev_fn === fn) return
298298
assert(typeof fn === 'function' || fn == null)
299-
cleanup?.()
300-
cleanup = fn?.(node)
299+
try {
300+
cleanup?.()
301+
} finally {
302+
cleanup = fn?.(node)
303+
}
301304
prev_fn = fn
302305
}
303306
}

src/client/tests/directives.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,31 @@ test('same directive function is not re-invoked or cleaned up', () => {
243243
root.render(template(null, null))
244244
assert_deep_eq(sequence, ['stable cleanup', 'unstable cleanup'])
245245
})
246+
247+
test('cleanup can throw and next directive will still run', () => {
248+
const { root, el } = setup()
249+
250+
const template = (d: Directive | null) => html`<div ${d}>Hello, world!</div>`
251+
252+
const oops = new Error('oops')
253+
254+
root.render(
255+
template(() => () => {
256+
throw oops
257+
}),
258+
)
259+
260+
let caught
261+
try {
262+
root.render(
263+
template(node => {
264+
;(node as HTMLElement).style.color = 'red'
265+
}),
266+
)
267+
} catch (error) {
268+
caught = error
269+
}
270+
271+
assert_eq(caught, oops)
272+
assert_eq(el.querySelector('div')!.style.cssText, 'color: red;')
273+
})

0 commit comments

Comments
 (0)