@sveltejs/kit 3.0.0-next.10 → 3.0.0-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package.json +1 -1
  2. package/src/constants.js +2 -0
  3. package/src/core/adapt/builder.js +3 -6
  4. package/src/core/config/index.js +6 -1
  5. package/src/core/config/options.js +11 -69
  6. package/src/core/postbuild/fallback.js +2 -1
  7. package/src/core/postbuild/prerender.js +75 -28
  8. package/src/core/postbuild/queue.js +2 -1
  9. package/src/core/sync/write_server.js +2 -2
  10. package/src/core/utils.js +28 -3
  11. package/src/exports/env/index.js +68 -3
  12. package/src/exports/internal/env.js +6 -3
  13. package/src/exports/params.js +9 -4
  14. package/src/exports/public.d.ts +41 -20
  15. package/src/exports/vite/dev/index.js +50 -6
  16. package/src/exports/vite/index.js +130 -125
  17. package/src/exports/vite/module_ids.js +0 -2
  18. package/src/exports/vite/preview/index.js +3 -2
  19. package/src/exports/vite/utils.js +20 -0
  20. package/src/runtime/app/paths/server.js +1 -1
  21. package/src/runtime/app/server/index.js +1 -1
  22. package/src/runtime/app/server/remote/query.js +1 -1
  23. package/src/runtime/client/ndjson.js +1 -1
  24. package/src/runtime/client/stream.js +3 -2
  25. package/src/runtime/server/data/index.js +1 -1
  26. package/src/runtime/server/errors.js +135 -0
  27. package/src/runtime/server/fetch.js +1 -1
  28. package/src/runtime/server/index.js +20 -10
  29. package/src/runtime/server/internal.js +25 -0
  30. package/src/runtime/server/page/actions.js +2 -1
  31. package/src/runtime/server/page/data_serializer.js +10 -10
  32. package/src/runtime/server/page/index.js +3 -2
  33. package/src/runtime/server/page/load_data.js +1 -1
  34. package/src/runtime/server/page/render.js +3 -7
  35. package/src/runtime/server/page/respond_with_error.js +6 -5
  36. package/src/runtime/server/{remote.js → remote-functions.js} +1 -1
  37. package/src/runtime/server/respond.js +3 -7
  38. package/src/runtime/server/sourcemaps.js +183 -0
  39. package/src/runtime/server/utils.js +2 -157
  40. package/src/types/ambient-private.d.ts +2 -0
  41. package/src/types/global-private.d.ts +0 -5
  42. package/src/types/internal.d.ts +6 -6
  43. package/src/types/private.d.ts +8 -0
  44. package/src/utils/escape.js +9 -25
  45. package/src/utils/features.js +1 -1
  46. package/src/utils/fork.js +7 -2
  47. package/src/utils/page_nodes.js +3 -5
  48. package/src/version.js +1 -1
  49. package/types/index.d.ts +72 -22
  50. package/types/index.d.ts.map +3 -1
  51. package/src/runtime/shared-server.js +0 -7
@@ -2,10 +2,10 @@ import { noop } from '../../utils/functions.js';
2
2
  import { IN_WEBCONTAINER } from './constants.js';
3
3
  import { respond } from './respond.js';
4
4
  import { options, get_hooks } from '__SERVER__/internal.js';
5
- import { format_server_error } from './utils.js';
6
- import { set_read_implementation, set_manifest } from '__sveltekit/server';
5
+ import { set_read_implementation, set_manifest } from './internal.js';
7
6
  import { set_env } from '__sveltekit/env';
8
7
  import { set_app } from './app.js';
8
+ import { SvelteKitError } from '@sveltejs/kit/internal';
9
9
 
10
10
  /** @type {Promise<any>} */
11
11
  let init_promise;
@@ -107,13 +107,23 @@ export class Server {
107
107
  handle: module.handle || (({ event, resolve }) => resolve(event)),
108
108
  handleError:
109
109
  module.handleError ||
110
- (({ status, error, event }) => {
111
- const error_message = format_server_error(
112
- status,
113
- /** @type {Error} */ (error),
114
- event
115
- );
116
- console.error(error_message);
110
+ (({ error }) => {
111
+ if (error instanceof SvelteKitError) {
112
+ // don't log stack traces for 404s etc, it's all internal gubbins
113
+ return;
114
+ }
115
+
116
+ let e = error;
117
+ while (e instanceof Error) {
118
+ if (e.stack) {
119
+ console.error(e.stack);
120
+ }
121
+ e = e.cause;
122
+ }
123
+
124
+ if (e) {
125
+ console.error(String(e));
126
+ }
117
127
  }),
118
128
  handleFetch: module.handleFetch || (({ request, fetch }) => fetch(request)),
119
129
  handleValidationError:
@@ -164,7 +174,7 @@ export class Server {
164
174
  * @param {Request} request
165
175
  * @param {import('types').RequestOptions} options
166
176
  */
167
- async respond(request, options) {
177
+ respond(request, options) {
168
178
  return respond(request, this.#options, this.#manifest, {
169
179
  ...options,
170
180
  error: false,
@@ -0,0 +1,25 @@
1
+ /** @import { SSRManifest } from '@sveltejs/kit'; */
2
+
3
+ /**
4
+ * @type {((path: string) => ReadableStream<any>) | null}
5
+ */
6
+ export let read_implementation = null;
7
+
8
+ export let manifest = /** @type {SSRManifest} */ (/** @type {unknown} */ (null));
9
+
10
+ /**
11
+ * @param {(path: string) => ReadableStream<any>} fn
12
+ */
13
+ export function set_read_implementation(fn) {
14
+ read_implementation = fn;
15
+ }
16
+
17
+ /**
18
+ *
19
+ * @param {SSRManifest} value
20
+ */
21
+ export function set_manifest(value) {
22
+ manifest = value;
23
+ }
24
+
25
+ export { fix_stack_trace, set_fix_stack_trace } from './sourcemaps.js';
@@ -7,7 +7,8 @@ import { HttpError, Redirect, ActionFailure, SvelteKitError } from '@sveltejs/ki
7
7
  import { with_request_store, merge_tracing } from '@sveltejs/kit/internal/server';
8
8
  import { normalize_error } from '../../../utils/error.js';
9
9
  import { is_form_content_type, negotiate } from '../../../utils/http.js';
10
- import { create_replacer, handle_error_and_jsonify } from '../utils.js';
10
+ import { create_replacer } from '../utils.js';
11
+ import { handle_error_and_jsonify } from '../errors.js';
11
12
  import { record_span } from '../../telemetry/record_span.js';
12
13
 
13
14
  /** @param {RequestEvent} event */
@@ -1,12 +1,8 @@
1
1
  import * as devalue from 'devalue';
2
2
  import { compact } from '../../../utils/array.js';
3
3
  import { create_async_iterator } from '../../../utils/streaming.js';
4
- import {
5
- clarify_devalue_error,
6
- get_global_name,
7
- handle_error_and_jsonify,
8
- serialize_uses
9
- } from '../utils.js';
4
+ import { clarify_devalue_error, get_global_name, serialize_uses } from '../utils.js';
5
+ import { handle_error_and_jsonify } from '../errors.js';
10
6
 
11
7
  /**
12
8
  * If the serialized data contains promises, `chunks` will be an
@@ -45,12 +41,14 @@ export function server_data_serializer(event, event_state, options) {
45
41
  let str;
46
42
  try {
47
43
  str = devalue.uneval(error ? [, error] : [data], replacer);
48
- } catch {
44
+ } catch (e) {
49
45
  error = await handle_error_and_jsonify(
50
46
  event,
51
47
  event_state,
52
48
  options,
53
- new Error(`Failed to serialize promise while rendering ${event.route.id}`)
49
+ new Error(`Failed to serialize promise while rendering ${event.route.id}`, {
50
+ cause: e
51
+ })
54
52
  );
55
53
  str = devalue.uneval([, error], replacer);
56
54
  }
@@ -164,12 +162,14 @@ export function server_data_serializer_json(event, event_state, options) {
164
162
  let str;
165
163
  try {
166
164
  str = devalue.stringify(value, reducers);
167
- } catch {
165
+ } catch (e) {
168
166
  const error = await handle_error_and_jsonify(
169
167
  event,
170
168
  event_state,
171
169
  options,
172
- new Error(`Failed to serialize promise while rendering ${event.route.id}`)
170
+ new Error(`Failed to serialize promise while rendering ${event.route.id}`, {
171
+ cause: e
172
+ })
173
173
  );
174
174
 
175
175
  key = 'error';
@@ -7,7 +7,8 @@ import { compact } from '../../../utils/array.js';
7
7
  import { get_status, normalize_error } from '../../../utils/error.js';
8
8
  import { noop } from '../../../utils/functions.js';
9
9
  import { add_data_suffix } from '../../pathname.js';
10
- import { redirect_response, static_error_page, handle_error_and_jsonify } from '../utils.js';
10
+ import { redirect_response } from '../utils.js';
11
+ import { static_error_page, handle_error_and_jsonify } from '../errors.js';
11
12
  import {
12
13
  handle_action_json_request,
13
14
  handle_action_request,
@@ -19,7 +20,7 @@ import { load_data, load_server_data } from './load_data.js';
19
20
  import { render_response } from './render.js';
20
21
  import { respond_with_error } from './respond_with_error.js';
21
22
  import { DEV } from 'esm-env';
22
- import { get_remote_action, handle_remote_form_post } from '../remote.js';
23
+ import { get_remote_action, handle_remote_form_post } from '../remote-functions.js';
23
24
  import { PageNodes } from '../../../utils/page_nodes.js';
24
25
 
25
26
  /**
@@ -465,7 +465,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
465
465
  const included = resolve_opts.filterSerializedResponseHeaders(lower, value);
466
466
  if (!included) {
467
467
  throw new Error(
468
- `Failed to get response header "${lower}" — it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#Server-hooks-handle (at ${event.route.id})`
468
+ `Failed to get response header "${lower}" — it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#handle (at ${event.route.id})`
469
469
  );
470
470
  }
471
471
  }
@@ -14,14 +14,10 @@ import { create_server_routing_response, generate_route_object } from './server_
14
14
  import { add_data_suffix, add_resolution_suffix } from '../../pathname.js';
15
15
  import { try_get_request_store, with_request_store } from '@sveltejs/kit/internal/server';
16
16
  import { text_encoder } from '../../utils.js';
17
- import {
18
- count_non_ssi_comments,
19
- create_replacer,
20
- get_global_name,
21
- handle_error_and_jsonify
22
- } from '../utils.js';
17
+ import { count_non_ssi_comments, create_replacer, get_global_name } from '../utils.js';
18
+ import { handle_error_and_jsonify } from '../errors.js';
23
19
  import * as env from '__sveltekit/env';
24
- import { collect_remote_data } from '../remote.js';
20
+ import { collect_remote_data } from '../remote-functions.js';
25
21
  import Root from '../../components/root.svelte';
26
22
  import { render } from 'svelte/server';
27
23
 
@@ -1,7 +1,8 @@
1
1
  import { Redirect } from '@sveltejs/kit/internal';
2
2
  import { render_response } from './render.js';
3
3
  import { load_data, load_server_data } from './load_data.js';
4
- import { handle_error_and_jsonify, static_error_page, redirect_response } from '../utils.js';
4
+ import { redirect_response } from '../utils.js';
5
+ import { handle_error_and_jsonify, static_error_page } from '../errors.js';
5
6
  import { PageNodes } from '../../../utils/page_nodes.js';
6
7
  import { server_data_serializer } from './data_serializer.js';
7
8
 
@@ -33,12 +34,12 @@ export async function respond_with_error({
33
34
  }) {
34
35
  // reroute to the fallback page to prevent an infinite chain of requests.
35
36
  if (event.request.headers.get('x-sveltekit-error')) {
36
- return static_error_page(options, status, /** @type {Error} */ (error).message);
37
+ const transformed = await handle_error_and_jsonify(event, event_state, options, error);
38
+ return static_error_page(options, status, transformed.message);
37
39
  }
38
40
 
39
41
  /** @type {import('./types.js').Fetched[]} */
40
42
  const fetched = [];
41
-
42
43
  try {
43
44
  const branch = [];
44
45
  const default_layout = await manifest._.nodes[0](); // 0 is always the root layout
@@ -46,6 +47,8 @@ export async function respond_with_error({
46
47
  const ssr = nodes.ssr();
47
48
  const csr = nodes.csr();
48
49
  const data_serializer = server_data_serializer(event, event_state, options);
50
+ // Do this here first in case the awaits below before rendering themselves error
51
+ const transformed = await handle_error_and_jsonify(event, event_state, options, error);
49
52
 
50
53
  if (ssr) {
51
54
  state.error = true;
@@ -89,8 +92,6 @@ export async function respond_with_error({
89
92
  );
90
93
  }
91
94
 
92
- const transformed = await handle_error_and_jsonify(event, event_state, options, error);
93
-
94
95
  return await render_response({
95
96
  options,
96
97
  manifest,
@@ -7,7 +7,7 @@ import { with_request_store, merge_tracing } from '@sveltejs/kit/internal/server
7
7
  import { app_dir, base } from '$app/paths/internal/server';
8
8
  import { is_form_content_type } from '../../utils/http.js';
9
9
  import { create_remote_key, parse_remote_arg, split_remote_key, stringify } from '../shared.js';
10
- import { handle_error_and_jsonify } from './utils.js';
10
+ import { handle_error_and_jsonify } from './errors.js';
11
11
  import { normalize_error } from '../../utils/error.js';
12
12
  import { check_incorrect_fail_use } from './page/actions.js';
13
13
  import { DEV } from 'esm-env';
@@ -9,12 +9,8 @@ import { render_page } from './page/index.js';
9
9
  import { render_response } from './page/render.js';
10
10
  import { respond_with_error } from './page/respond_with_error.js';
11
11
  import { get_self_origin, is_csrf_forbidden, is_remote_forbidden } from './csrf.js';
12
- import {
13
- handle_fatal_error,
14
- has_prerendered_path,
15
- method_not_allowed,
16
- redirect_response
17
- } from './utils.js';
12
+ import { has_prerendered_path, method_not_allowed, redirect_response } from './utils.js';
13
+ import { handle_fatal_error } from './errors.js';
18
14
  import { decode_pathname, disable_search, normalize_path } from '../../utils/url.js';
19
15
  import { find_route } from '../../utils/routing.js';
20
16
  import { redirect_json_response, render_data } from './data/index.js';
@@ -36,7 +32,7 @@ import {
36
32
  strip_resolution_suffix
37
33
  } from '../pathname.js';
38
34
  import { server_data_serializer } from './page/data_serializer.js';
39
- import { get_remote_id, handle_remote_call } from './remote.js';
35
+ import { get_remote_id, handle_remote_call } from './remote-functions.js';
40
36
  import { record_span } from '../telemetry/record_span.js';
41
37
  import { otel } from '../telemetry/otel.js';
42
38
 
@@ -0,0 +1,183 @@
1
+ /* eslint-disable n/prefer-global/process */
2
+
3
+ // using `getBuiltinModule` rather than `import` makes this safe to run in non-Node-compatible environments
4
+ const fs = globalThis.process?.getBuiltinModule?.('node:fs');
5
+ const url = globalThis.process?.getBuiltinModule?.('node:url');
6
+ const path = globalThis.process?.getBuiltinModule?.('node:path');
7
+ const module = globalThis.process?.getBuiltinModule?.('node:module');
8
+
9
+ const cwd = globalThis.process?.cwd?.();
10
+
11
+ /** @type {(file: string) => string} */
12
+ const relative = cwd ? (file) => path.relative(cwd, file) : (file) => file;
13
+
14
+ /**
15
+ * Applies sourcemaps, makes paths relative to the cwd, and truncates
16
+ * non-user code from the bottom of the stack
17
+ * @param {Error} error
18
+ * @returns void
19
+ */
20
+ export let fix_stack_trace = (error) => {
21
+ if (!error.stack || !fs) return;
22
+
23
+ let end = 0;
24
+
25
+ error.stack = error.stack
26
+ .split('\n')
27
+ .map((line, i) => {
28
+ const match = line.match(/^ {4}at.+(file:\/\/\/.*):(\d+):(\d+)(\)?)$/);
29
+
30
+ if (!match) {
31
+ if (!line.includes('node:internal/')) {
32
+ end = i + 1;
33
+ }
34
+
35
+ return line;
36
+ }
37
+
38
+ const file = url.fileURLToPath(match[1]);
39
+ const traced = trace(file, Number(match[2]) - 1, Number(match[3]) - 1);
40
+
41
+ // truncate non-user code from the bottom of the stack (but leave it in otherwise)
42
+ if (!/[\\/]node_modules[\\/]/.test(traced?.file ?? file)) {
43
+ end = i + 1;
44
+ }
45
+
46
+ if (traced?.line) {
47
+ const location = `${match[1]}:${match[2]}:${match[3]}`;
48
+ const original = `${relative(traced.file)}:${traced.line}:${traced.column}`;
49
+
50
+ return line.replace(location, original);
51
+ }
52
+
53
+ if (traced) {
54
+ return `${line.replace(match[1], relative(file))} [${traced.file}]`;
55
+ }
56
+
57
+ return line;
58
+ })
59
+ .slice(0, end)
60
+ .join('\n');
61
+ };
62
+
63
+ /**
64
+ * Override the implementation of fix_stack_trace (for using during dev)
65
+ * @param {(error: Error) => void} fn
66
+ */
67
+ export function set_fix_stack_trace(fn) {
68
+ fix_stack_trace = fn;
69
+ }
70
+
71
+ /** @type {Map<string, { map: import('node:module').SourceMap; directory: string } | null>} */
72
+ const source_maps = new Map();
73
+
74
+ /** @type {Map<string, Array<string | undefined>>} */
75
+ const source_regions = new Map();
76
+
77
+ /** @param {string} file */
78
+ function get_source_map(file) {
79
+ if (source_maps.has(file)) {
80
+ return source_maps.get(file);
81
+ }
82
+
83
+ try {
84
+ let source;
85
+ let directory = path.dirname(file);
86
+
87
+ const code = fs.readFileSync(file, 'utf8');
88
+ const matches = Array.from(code.matchAll(/\/\/[#@]\s*sourceMappingURL=(\S+)/g));
89
+ const url = matches.at(-1)?.[1];
90
+
91
+ if (url?.startsWith('data:')) {
92
+ const comma = url.indexOf(',');
93
+ const metadata = url.slice(5, comma);
94
+ const data = url.slice(comma + 1);
95
+ source = metadata.endsWith(';base64')
96
+ ? Buffer.from(data, 'base64').toString()
97
+ : decodeURIComponent(data);
98
+ } else {
99
+ const map_file = url
100
+ ? path.resolve(path.dirname(file), decodeURIComponent(url))
101
+ : `${file}.map`;
102
+ if (fs.existsSync(map_file)) {
103
+ directory = path.dirname(map_file);
104
+ source = fs.readFileSync(map_file, 'utf8');
105
+ }
106
+ }
107
+
108
+ if (source) {
109
+ const source_map = { map: new module.SourceMap(JSON.parse(source)), directory };
110
+ source_maps.set(file, source_map);
111
+
112
+ return source_map;
113
+ }
114
+ } catch {
115
+ // failure could be for any reason and this is best-effort, ignore
116
+ }
117
+
118
+ source_maps.set(file, null);
119
+ return null;
120
+ }
121
+
122
+ /**
123
+ *
124
+ * @param {string} file
125
+ * @param {number} line
126
+ * @param {number} column
127
+ * @returns {null | { file: string, line?: number, column?: number }}
128
+ */
129
+ function trace(file, line, column) {
130
+ const source_map = get_source_map(file);
131
+ if (!source_map) return null;
132
+
133
+ const entry = source_map.map.findEntry(line, column);
134
+
135
+ if (
136
+ entry &&
137
+ 'originalSource' in entry &&
138
+ entry.originalSource &&
139
+ typeof entry.originalLine === 'number' &&
140
+ typeof entry.originalColumn === 'number'
141
+ ) {
142
+ const source = entry.originalSource.startsWith('file:')
143
+ ? url.fileURLToPath(entry.originalSource)
144
+ : path.resolve(source_map.directory, entry.originalSource);
145
+
146
+ const traced = {
147
+ file: source,
148
+ line: entry.originalLine + 1,
149
+ column: entry.originalColumn + 1
150
+ };
151
+
152
+ // keep going, in case we are running code that was bundled a second time by an adapter
153
+ return trace(traced.file, traced.line - 1, traced.column - 1) ?? traced;
154
+ }
155
+
156
+ let regions = source_regions.get(file);
157
+ if (!regions) {
158
+ /** @type {string | undefined} */
159
+ let source;
160
+ regions = fs
161
+ .readFileSync(file, 'utf8')
162
+ .split('\n')
163
+ .map((line) => {
164
+ // Vite will merge multiple files into one but add region markers
165
+ // with the original file names, which we try to extract here.
166
+ const start = line.match(/^\/\/#region (.+)$/);
167
+ if (start) source = start[1];
168
+ if (line === '//#endregion') source = undefined;
169
+ return source;
170
+ });
171
+ source_regions.set(file, regions);
172
+ }
173
+
174
+ const source = regions[line];
175
+
176
+ if (source) {
177
+ return {
178
+ file: source
179
+ };
180
+ }
181
+
182
+ return null;
183
+ }
@@ -1,15 +1,7 @@
1
1
  /** @import { ServerHooks } from 'types' */
2
2
  import * as devalue from 'devalue';
3
- import { DEV } from 'esm-env';
4
- import { json, text } from '@sveltejs/kit';
5
- import { HttpError } from '@sveltejs/kit/internal';
6
- import { with_request_store } from '@sveltejs/kit/internal/server';
7
- import { coalesce_to_error, get_message, get_status } from '../../utils/error.js';
8
- import { negotiate } from '../../utils/http.js';
9
- import { fix_stack_trace } from '../shared-server.js';
3
+ import { text } from '@sveltejs/kit';
10
4
  import { ENDPOINT_METHODS } from '../../constants.js';
11
- import { escape_html } from '../../utils/escape.js';
12
- import * as path from '../../utils/path.js';
13
5
 
14
6
  /**
15
7
  * @param {Partial<Record<import('types').HttpMethod, any>>} mod
@@ -46,103 +38,6 @@ export function get_global_name(options) {
46
38
  return __SVELTEKIT_DEV__ ? '__sveltekit_dev' : `__sveltekit_${options.version_hash}`;
47
39
  }
48
40
 
49
- /**
50
- * Return as a response that renders the error.html
51
- *
52
- * @param {import('types').SSROptions} options
53
- * @param {number} status
54
- * @param {string} message
55
- */
56
- export function static_error_page(options, status, message) {
57
- let page = options.templates.error({ status, message: escape_html(message) });
58
-
59
- if (__SVELTEKIT_DEV__) {
60
- // inject Vite HMR client, for easier debugging
61
- page = page.replace('</head>', '<script type="module" src="/@vite/client"></script></head>');
62
- }
63
-
64
- return text(page, {
65
- headers: { 'content-type': 'text/html; charset=utf-8' },
66
- status
67
- });
68
- }
69
-
70
- /**
71
- * @param {import('@sveltejs/kit').RequestEvent} event
72
- * @param {import('types').RequestState} state
73
- * @param {import('types').SSROptions} options
74
- * @param {unknown} error
75
- */
76
- export async function handle_fatal_error(event, state, options, error) {
77
- error = error instanceof HttpError ? error : coalesce_to_error(error);
78
- const body = await handle_error_and_jsonify(event, state, options, error);
79
- const status = body.status;
80
-
81
- // ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it
82
- const type = negotiate(event.request.headers.get('accept') || 'text/html', [
83
- 'application/json',
84
- 'text/html'
85
- ]);
86
-
87
- if (event.isDataRequest || type === 'application/json') {
88
- return json(body, {
89
- status
90
- });
91
- }
92
-
93
- return static_error_page(options, status, body.message);
94
- }
95
-
96
- /**
97
- * @param {import('@sveltejs/kit').RequestEvent} event
98
- * @param {import('types').RequestState} state
99
- * @param {import('types').SSROptions} options
100
- * @param {any} error
101
- * @returns {App.Error | Promise<App.Error>}
102
- */
103
- export function handle_error_and_jsonify(event, state, options, error) {
104
- if (error instanceof HttpError) {
105
- // @ts-expect-error custom user errors may not have a message field if App.Error is overwritten
106
- return { message: 'Unknown Error', ...error.body };
107
- }
108
-
109
- if (__SVELTEKIT_DEV__ && typeof error == 'object') {
110
- fix_stack_trace(error);
111
- }
112
-
113
- const status = get_status(error);
114
- const message = get_message(error);
115
-
116
- // TODO 4.0 await this, rather than handling the non-Promise case
117
- const result = with_request_store({ event, state }, () =>
118
- options.hooks.handleError({ error, event, status, message })
119
- ) ?? { status, message };
120
-
121
- if (result instanceof Promise) {
122
- if (!__SVELTEKIT_SUPPORTS_ASYNC__ && state.is_in_render) {
123
- console.warn(
124
- `To use an async \`handleError\` hook to handle errors that occur during rendering, you must enable \`compilerOptions.experimental.async\` in the SvelteKit plugin of your Vite config. The returned error has been replaced with a generic object`
125
- );
126
-
127
- // we're discarding the result, but we still need to prevent an unhandled
128
- // rejection if the user's async `handleError` hook rejects
129
- result.catch(() => {});
130
-
131
- return {
132
- status,
133
- message: 'Internal Error'
134
- };
135
- }
136
-
137
- return result.then((body) => {
138
- body ??= { status, message };
139
- return { ...body, status: get_status(body, error) };
140
- });
141
- }
142
-
143
- return { ...result, status: get_status(result, error) };
144
- }
145
-
146
41
  /**
147
42
  * @param {number} status
148
43
  * @param {string} location
@@ -163,7 +58,7 @@ export function clarify_devalue_error(event, error) {
163
58
  if (error.path) {
164
59
  return (
165
60
  `Data returned from \`load\` while rendering ${event.route.id} is not serializable: ${error.message} (${error.path}). ` +
166
- `If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#Universal-hooks-transport.`
61
+ `If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#transport.`
167
62
  );
168
63
  }
169
64
 
@@ -212,56 +107,6 @@ export function has_prerendered_path(manifest, pathname) {
212
107
  );
213
108
  }
214
109
 
215
- /**
216
- * Formats the error into a nice message with sanitized stack trace
217
- * @param {number} status
218
- * @param {Error} error
219
- * @param {import('@sveltejs/kit').RequestEvent} event
220
- */
221
- export function format_server_error(status, error, event) {
222
- const formatted_text = `\n\x1b[1;31m[${status}] ${event.request.method} ${event.url.pathname}\x1b[0m`;
223
-
224
- if (status === 404) {
225
- return formatted_text;
226
- }
227
-
228
- return `${formatted_text}\n${DEV ? clean_up_stack_trace(error) : error.stack}`;
229
- }
230
-
231
- /**
232
- * In dev, tidy up stack traces by making paths relative to the current project directory
233
- * @param {string} file
234
- */
235
- let relative = (file) => file;
236
-
237
- if (DEV) {
238
- try {
239
- relative = (file) => path.relative(__SVELTEKIT_ROOT__, file);
240
- } catch {
241
- // do nothing
242
- }
243
- }
244
-
245
- /**
246
- * Provides a refined stack trace by excluding lines following the last occurrence of a line containing +page. +layout. or +server.
247
- * @param {Error} error
248
- */
249
- export function clean_up_stack_trace(error) {
250
- const stack_trace = (error.stack?.split('\n') ?? []).map((line) => {
251
- return line.replace(/\((.+)(:\d+:\d+)\)$/, (_, file, loc) => `(${relative(file)}${loc})`);
252
- });
253
-
254
- // progressive enhancement for people who haven't configured files.src to something else
255
- const last_line_from_src_code = stack_trace.findLastIndex((line) => /\(src[\\/]/.test(line));
256
-
257
- if (last_line_from_src_code === -1) {
258
- // default to the whole stack trace
259
- return error.stack;
260
- }
261
-
262
- return stack_trace.slice(0, last_line_from_src_code + 1).join('\n');
263
- }
264
-
265
110
  /**
266
111
  * Returns the filename without the extension. e.g., `+page.server`, `+page`, etc.
267
112
  * @param {string | undefined} node_id
@@ -13,8 +13,10 @@ declare module '__sveltekit/paths' {
13
13
  declare module '__sveltekit/server' {
14
14
  import { SSRManifest } from '@sveltejs/kit';
15
15
 
16
+ export let fix_stack_trace: (error: Error) => string;
16
17
  export let manifest: SSRManifest;
17
18
  export function read_implementation(path: string): ReadableStream;
19
+ export function set_fix_stack_trace(fn: (error: Error) => string): void;
18
20
  export function set_manifest(manifest: SSRManifest): void;
19
21
  export function set_read_implementation(fn: (path: string) => ReadableStream): void;
20
22
  }
@@ -38,11 +38,6 @@ declare global {
38
38
  * Should only be used when bundleStrategy !== 'inline' to avoid SvelteKit runtime changing on every build, preventing cacheability.
39
39
  */
40
40
  const __SVELTEKIT_PAYLOAD__: SvelteKitPayload;
41
- /**
42
- * The Vite `root` setting used to construct paths to nodes and components
43
- * for the SSR manifest during development
44
- */
45
- const __SVELTEKIT_ROOT__: string;
46
41
  /**
47
42
  * Whether the `experimental.async` flag is applied
48
43
  */