diff --git a/.changeset/hydration-custom-element-error-boundary.md b/.changeset/hydration-custom-element-error-boundary.md new file mode 100644 index 0000000000..f94aa6265a --- /dev/null +++ b/.changeset/hydration-custom-element-error-boundary.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: restore hydration state when custom element attribute updates throw diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 7d2dd62baf..982a405f98 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -298,196 +298,202 @@ function set_attributes( var is_option_element = element.nodeName === OPTION_TAG; var is_select_element = element.nodeName === SELECT_TAG; - for (var key in prev) { - // don't null our internal $$onX listeners - if (!(key in next) && key[0] + key[1] !== '$$') { - next[key] = null; - } - } - - if (next.class) { - next.class = clsx(next.class); - } else if (css_hash || next[CLASS]) { - next.class = null; /* force call to set_class() */ - } - - if (next[STYLE]) { - next.style ??= null; /* force call to set_style() */ - } - - var setters = get_setters(element); - - if (element.nodeName === INPUT_TAG && 'type' in next && ('value' in next || '__value' in next)) { - var type = next.type; - - if (type !== current.type || (type === undefined && element.hasAttribute('type'))) { - current.type = type; - set_attribute(element, 'type', type, skip_warning); + try { + for (var key in prev) { + // don't null our internal $$onX listeners + if (!(key in next) && key[0] + key[1] !== '$$') { + next[key] = null; + } } - } - // since key is captured we use const - for (const key in next) { - // let instead of var because referenced in a closure - let value = next[key]; - - // Up here because we want to do this for the initial value, too, even if it's undefined, - // and this wouldn't be reached in case of undefined because of the equality check below - if (is_option_element && key === 'value' && value == null) { - // The