diff --git a/.changeset/serious-llamas-smoke.md b/.changeset/serious-llamas-smoke.md new file mode 100644 index 000000000000..7a33ae3e3998 --- /dev/null +++ b/.changeset/serious-llamas-smoke.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +[fix] more informative serialization error messages diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js index 3e0ea38903cc..33c9a68a71c0 100644 --- a/packages/kit/src/runtime/server/data/index.js +++ b/packages/kit/src/runtime/server/data/index.js @@ -111,7 +111,7 @@ export async function render_data(event, route, options, state) { nodes: nodes.slice(0, length) }; - return data_response(server_data); + return data_response(server_data, event); } catch (e) { const error = normalize_error(e); @@ -122,10 +122,10 @@ export async function render_data(event, route, options, state) { location: error.location }; - return data_response(server_data); + return data_response(server_data, event); } else { // TODO make it clearer that this was an unexpected error - return data_response(handle_error_and_jsonify(event, options, error)); + return data_response(handle_error_and_jsonify(event, options, error), event); } } } diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index eb5b7c187942..1c1d554ccff3 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -248,5 +248,9 @@ function check_serializability(value, id, path) { } } - throw new Error(`${path} returned from action in ${id} cannot be serialized as JSON`); + throw new Error( + `${path} returned from action in ${id} cannot be serialized as JSON without losing its original type` + + // probably the most common case, so let's give a hint + (value instanceof Date ? ' (Date objects are serialized as strings)' : '') + ); } diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index b26c4da88d8e..7953d33016c3 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -177,7 +177,11 @@ export async function render_response({ // function, but it would mean passing more stuff around than we currently do const error = /** @type {any} */ (e); const match = /\[(\d+)\]\.data\.(.+)/.exec(error.path); - if (match) throw new Error(`${error.message} (data.${match[2]})`); + if (match) { + throw new Error( + `Data returned from \`load\` while rendering /${event.routeId} is not serializable: ${error.message} (data.${match[2]})` + ); + } throw error; } diff --git a/packages/kit/src/runtime/server/utils.js b/packages/kit/src/runtime/server/utils.js index 08bc5437d8a4..33ef9b7c06ba 100644 --- a/packages/kit/src/runtime/server/utils.js +++ b/packages/kit/src/runtime/server/utils.js @@ -67,8 +67,11 @@ export function allowed_methods(mod) { return allowed; } -/** @param {any} data */ -export function data_response(data) { +/** + * @param {any} data + * @param {import('types').RequestEvent} event + */ +export function data_response(data, event) { const headers = { 'content-type': 'application/json', 'cache-control': 'private, no-store' @@ -79,7 +82,9 @@ export function data_response(data) { } catch (e) { const error = /** @type {any} */ (e); const match = /\[(\d+)\]\.data\.(.+)/.exec(error.path); - const message = match ? `${error.message} (data.${match[2]})` : error.message; + const message = match + ? `Data returned from \`load\` while rendering /${event.routeId} is not serializable: ${error.message} (data.${match[2]})` + : error.message; return new Response(JSON.stringify(message), { headers, status: 500 }); } } diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index 0588cdc6bc6a..9331e7708f72 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -308,7 +308,7 @@ test.describe('Shadowed pages', () => { expect(await page.textContent('h1')).toBe('500'); expect(await page.textContent('#message')).toBe( - 'This is your custom error page saying: "Cannot stringify arbitrary non-POJOs (data.nope)"' + 'This is your custom error page saying: "Data returned from `load` while rendering /shadowed/serialization is not serializable: Cannot stringify arbitrary non-POJOs (data.nope)"' ); }); }