svelte-material-ui
svelte-material-ui copied to clipboard
Tooltip crashes when inserting elements in `onDestroy`
Describe the bug
I'm seeing crashes when a component using multiple Wrapper and Tooltip is being destroyed. The error message is:
Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
and occurs here: https://github.com/hperrin/svelte-material-ui/blob/master/packages/tooltip/src/Tooltip.svelte#L320
It seems to me like it's related to elements being inside {#if} blocks. The code is about the following
<Wrapper>
<Button>...</Button>
<Tooltip>Foo</Tooltip>
</Wrapper>
<Wrapper>
<Button>...</Button>
<Tooltip>Foo</Tooltip>
</Wrapper>
{#if someProp}
<Button>...</Button>
{/if}
<Button on:click={toggleSomeProp}>...</Button>
This works fine until the component gets unmounted, at which point Tooltip will crash in the second Wrapper. There's no crash with a single Wrapper, or with only one tooltip.
This is the full callstack:
Tooltip.svelte?4208:476 Uncaught (in promise) DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
at eval (webpack-internal:///../../../node_modules/@smui/tooltip/dist/Tooltip.svelte:445:36)
at run (webpack-internal:///../../../node_modules/svelte/internal/index.mjs:196:12)
at Array.forEach (<anonymous>)
at run_all (webpack-internal:///../../../node_modules/svelte/internal/index.mjs:202:9)
at destroy_component (webpack-internal:///../../../node_modules/svelte/internal/index.mjs:1997:9)
at Object.destroy [as d] (webpack-internal:///./src/components/MyComponent.svelte:885:70)
at Object.destroy [as d] (webpack-internal:///../../../node_modules/@smui/tooltip/dist/Wrapper.svelte:64:35)
at Object.destroy [as d] (webpack-internal:///../../../node_modules/@smui/tooltip/dist/Wrapper.svelte:254:40)
at destroy_component (webpack-internal:///../../../node_modules/svelte/internal/index.mjs:1998:36)
at Object.destroy [as d] (webpack-internal:///./src/components/MyComponent.svelte:1848:70)
To Reproduce
This is the shortest repro I've been able to get: https://svelte.dev/repl/53b367ea32584baa9139eedcce75641f?version=3.48.0.
Unhelpfully, it generates this callstack:
caught (in promise) DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
at eval (eval at handle_message (about:srcdoc:14:8), <anonymous>:3510:40)
at run (eval at handle_message (about:srcdoc:14:8), <anonymous>:39:16)
at Array.forEach (<anonymous>)
at run_all (eval at handle_message (about:srcdoc:14:8), <anonymous>:45:13)
at destroy_component (eval at handle_message (about:srcdoc:14:8), <anonymous>:436:13)
at Object.destroy [as d] (eval at handle_message (about:srcdoc:14:8), <anonymous>:9851:8)
at Object.destroy [as d] (eval at handle_message (about:srcdoc:14:8), <anonymous>:4181:39)
at Object.destroy [as d] (eval at handle_message (about:srcdoc:14:8), <anonymous>:4370:44)
at destroy_component (eval at handle_message (about:srcdoc:14:8), <anonymous>:437:40)
at Object.destroy [as d] (eval at handle_message (about:srcdoc:14:8), <anonymous>:10033:8)
Which is useless but matches above.
Desktop (please complete the following information):
- OS: Windows
- Browser: Chrome
- Version: 101
I am also seeing this - It seems to happen for me when I have some elements that were created with tooltips and then I remove some of them from the DOM. The Tooltip onDestroy() - insertBefore is using "nonReactiveLocationStore.nextSibling" which is pointing to the element that was previously removed from the DOM causing insertBefore to crash.
FYI: Also wrapping the Wrapper with a div also seemed to resolved the issue. In this case the nonReactiveLocationStore.nextSibling was undefined, or it never got to that line.
@mwhebert Did you forget some code snippets in there? I'm guessing it was HTML and got stripped when posting. You might need to use a code block to ensure markdown doesn't to parse it.
```html
your code here
```
@mwhebert Did you forget some code snippets in there? I'm guessing it was HTML and got stripped when posting. You might need to use a code block to ensure markdown doesn't to parse it.
```html your code here ```
Thanks - I've updated the comment removing the angle brackets.