Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineEnvVars } from '@sveltejs/kit/hooks';
import { defineEnvVars } from '@sveltejs/kit/env';

// SvelteKit 3 makes "explicit environment variables" the default and removes the
// legacy `$env/*` virtual modules. Declared vars are imported from `$app/env/private`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ test.describe('server-side errors', () => {

expect(errorEventFrames?.[errorEventFrames?.length - 1]).toEqual(
expect.objectContaining({
filename: expect.stringMatching(/app:\/\/\/_server.ts-.+.js/),
filename: 'app:///src/routes/server-route-error/+server.ts',
function: 'GET',
in_app: true,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ export function rewriteFramesIteratee(frame: StackFrame): StackFrame {
strippedFilename = basename(filename);
}
frame.filename = `${prefix}${strippedFilename}`;
} else if (isAppRelativeSourceFrame(frame.filename)) {
// SvelteKit 3 (Vite/Rolldown) source-maps server frames to relative project paths such as
// `src/routes/+page.ts` instead of the previous bundled absolute chunk paths. These skip the
// branch above, so the default parser marks them as `in_app: false` (relative paths look like
// Node internals). Prefix them like the absolute frames and flag them as app code.
frame.filename = `${prefix}${frame.filename.replace(/^\.\//, '')}`;
frame.in_app = true;
}

delete frame.module;
Expand All @@ -80,3 +87,12 @@ export function rewriteFramesIteratee(frame: StackFrame): StackFrame {

return frame;
}

/**
* Whether a (non-absolute) frame filename is an app-relative source path like `src/routes/+page.ts`,
* as opposed to a dependency or a Node built-in. Excludes `node_modules` and any scheme/drive prefix
* (e.g. `node:`, `data:`, `C:/`).
*/
function isAppRelativeSourceFrame(filename: string): boolean {
return !filename.includes('node_modules/') && !/^[a-zA-Z][a-zA-Z0-9.+-]*:/.test(filename);
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,45 @@ describe('rewriteFramesIteratee', () => {
expect(result).toStrictEqual(originalResult);
});

it.each([
['src/routes/universal-load-error/+page.ts', 'app:///src/routes/universal-load-error/+page.ts'],
['./src/routes/server-load-error/+page.server.ts', 'app:///src/routes/server-load-error/+page.server.ts'],
['src/hooks.server.ts', 'app:///src/hooks.server.ts'],
])('rewrites and flags SvelteKit 3 app-relative source frames as in_app (%s)', (frameFilename, modifiedFilename) => {
const frame: StackFrame = {
filename: frameFilename,
lineno: 2,
colno: 9,
function: 'load',
};

const result = rewriteFramesIteratee({ ...frame });

expect(result).toStrictEqual({
filename: modifiedFilename,
lineno: 2,
colno: 9,
function: 'load',
in_app: true,
});
});

it.each([['node_modules/@sveltejs/kit/src/runtime/server/index.js'], ['node:internal/process/task_queues']])(
'does not rewrite or flag dependency/internal relative frames (%s)',
frameFilename => {
const frame: StackFrame = {
filename: frameFilename,
lineno: 1,
colno: 1,
};

const result = rewriteFramesIteratee({ ...frame });

expect(result.filename).toBe(frameFilename);
expect(result.in_app).toBeUndefined();
},
);

it.each([
['adapter-node', 'build', '/absolute/path/to/build/server/chunks/3-ab34d22f.js', 'app:///chunks/3-ab34d22f.js'],
[
Expand Down
Loading