diff --git a/runtime/src/server/middleware/get_page_handler.ts b/runtime/src/server/middleware/get_page_handler.ts index 40e6ef8fa..6a4d4f519 100644 --- a/runtime/src/server/middleware/get_page_handler.ts +++ b/runtime/src/server/middleware/get_page_handler.ts @@ -261,7 +261,7 @@ export function get_page_handler( session: session && try_serialize(session, err => { throw new Error(`Failed to serialize session data: ${err.message}`); }), - error: error && try_serialize(props.error) + error: error && serialize_error(props.error) }; let script = `__SAPPER__={${[ @@ -366,6 +366,20 @@ function try_serialize(data: any, fail?: (err) => void) { } } +// Ensure we return something truthy so the client will not re-render the page over the error +function serialize_error(error: Error | { message: string }) { + if (!error) return null; + let serialized = try_serialize(error); + if (!serialized) { + const { name, message, stack } = error as Error; + serialized = try_serialize({ name, message, stack }); + } + if (!serialized) { + serialized = '{}'; + } + return serialized; +} + function escape_html(html: string) { const chars: Record = { '"' : 'quot', diff --git a/test/apps/errors/src/routes/index.svelte b/test/apps/errors/src/routes/index.svelte index a6b7896db..5ccc389a2 100644 --- a/test/apps/errors/src/routes/index.svelte +++ b/test/apps/errors/src/routes/index.svelte @@ -2,4 +2,5 @@ nope blog/nope -throw \ No newline at end of file +throw +preload-reject \ No newline at end of file diff --git a/test/apps/errors/src/routes/preload-reject.svelte b/test/apps/errors/src/routes/preload-reject.svelte new file mode 100644 index 000000000..12a2e170d --- /dev/null +++ b/test/apps/errors/src/routes/preload-reject.svelte @@ -0,0 +1,7 @@ + + +

Test has failed

diff --git a/test/apps/errors/test.ts b/test/apps/errors/test.ts index 181c59189..f54c15cbf 100644 --- a/test/apps/errors/test.ts +++ b/test/apps/errors/test.ts @@ -85,6 +85,16 @@ describe('errors', function() { ); }); + it('does not replace server side rendered error', async () => { + await r.load('/preload-reject'); + await r.sapper.start(); + + assert.equal( + await r.text('h1'), + '500' + ); + }); + it('does not serve error page for explicit non-page errors', async () => { await r.load('/nope.json');