From 98849452b3eeaaede142188fa787cf8d7a300819 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Fri, 21 Nov 2025 16:09:19 -0700 Subject: [PATCH] make errors better --- .../98-reference/.generated/server-errors.md | 11 +++++++++ .../svelte/messages/server-errors/errors.md | 9 ++++++++ packages/svelte/src/internal/server/errors.js | 23 +++++++++++++++++++ .../svelte/src/internal/server/hydratable.js | 22 +++++++++++++++++- 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/documentation/docs/98-reference/.generated/server-errors.md b/documentation/docs/98-reference/.generated/server-errors.md index 95bb5fa7ee..6d852a7524 100644 --- a/documentation/docs/98-reference/.generated/server-errors.md +++ b/documentation/docs/98-reference/.generated/server-errors.md @@ -41,6 +41,17 @@ This error occurs when using `hydratable` multiple times with the same key. To a ``` +### hydratable_serialization_failed + +``` +Failed to serialize `hydratable` data. + +`hydratable` can serialize anything [`uneval` from `devalue`](https://npmjs.com/package/uneval) can, plus Promises. + +Stack: +%stack% +``` + ### lifecycle_function_unavailable ``` diff --git a/packages/svelte/messages/server-errors/errors.md b/packages/svelte/messages/server-errors/errors.md index be726b261a..30cf4cd2c2 100644 --- a/packages/svelte/messages/server-errors/errors.md +++ b/packages/svelte/messages/server-errors/errors.md @@ -33,6 +33,15 @@ This error occurs when using `hydratable` multiple times with the same key. To a ``` +## hydratable_serialization_failed + +> Failed to serialize `hydratable` data. +> +> `hydratable` can serialize anything [`uneval` from `devalue`](https://npmjs.com/package/uneval) can, plus Promises. +> +> Stack: +> %stack% + ## lifecycle_function_unavailable > `%name%(...)` is not available on the server diff --git a/packages/svelte/src/internal/server/errors.js b/packages/svelte/src/internal/server/errors.js index 480862b3c5..aab1659bf1 100644 --- a/packages/svelte/src/internal/server/errors.js +++ b/packages/svelte/src/internal/server/errors.js @@ -53,6 +53,29 @@ ${stack2}\nhttps://svelte.dev/e/hydratable_clobbering`); throw error; } +/** + * Failed to serialize `hydratable` data. + * + * `hydratable` can serialize anything [`uneval` from `devalue`](https://npmjs.com/package/uneval) can, plus Promises. + * + * Stack: + * %stack% + * @param {string} stack + * @returns {never} + */ +export function hydratable_serialization_failed(stack) { + const error = new Error(`hydratable_serialization_failed\nFailed to serialize \`hydratable\` data. + +\`hydratable\` can serialize anything [\`uneval\` from \`devalue\`](https://npmjs.com/package/uneval) can, plus Promises. + +Stack: +${stack}\nhttps://svelte.dev/e/hydratable_serialization_failed`); + + error.name = 'Svelte error'; + + throw error; +} + /** * `%name%(...)` is not available on the server * @param {string} name diff --git a/packages/svelte/src/internal/server/hydratable.js b/packages/svelte/src/internal/server/hydratable.js index 3beb5d50c2..6abc1e2735 100644 --- a/packages/svelte/src/internal/server/hydratable.js +++ b/packages/svelte/src/internal/server/hydratable.js @@ -66,7 +66,12 @@ function encode(key, value, values, unresolved) { needs_thunk = false; return result; }; - const serialize_promise = value.then(scoped_uneval); + const serialize_promise = value + .then(scoped_uneval) + .catch((devalue_error) => + e.hydratable_serialization_failed(serialization_stack(entry.stack, devalue_error?.stack)) + ); + serialize_promise.catch(() => {}); unresolved?.set(serialize_promise, key); serialize_promise.finally(() => unresolved?.delete(serialize_promise)); @@ -123,3 +128,18 @@ async function compare(key, a, b) { ); } } + +/** + * @param {string | undefined} root_stack + * @param {string | undefined} uneval_stack + */ +function serialization_stack(root_stack, uneval_stack) { + let out = ''; + if (root_stack) { + out += root_stack + '\n'; + } + if (uneval_stack) { + out += 'Caused by:\n' + uneval_stack + '\n'; + } + return out || ''; +}