diff --git a/packages/plugin-rsc/e2e/source-map.test.ts b/packages/plugin-rsc/e2e/source-map.test.ts
index 06de38eb0..9ad059dc7 100644
--- a/packages/plugin-rsc/e2e/source-map.test.ts
+++ b/packages/plugin-rsc/e2e/source-map.test.ts
@@ -189,6 +189,30 @@ test.describe('source map', () => {
}
})
}
+
+ test('preserves Server Function names in stack traces', async ({ page }) => {
+ await page.goto(f.url('/server-function-name'))
+ await waitForHydration(page)
+
+ const cases = [
+ {
+ referenceName: 'module-function-name',
+ functionName: 'moduleFunctionName',
+ },
+ {
+ referenceName: 'inline-function-name',
+ functionName: 'inlineFunctionName',
+ },
+ ]
+
+ for (const item of cases) {
+ const button = page.getByRole('button', {
+ name: new RegExp(`^${item.referenceName}:`),
+ })
+ await button.click()
+ await expect(button).toContainText(`at ${item.functionName} (`)
+ }
+ })
})
async function createFunctionSourceMapResolver(page: Page, baseURL: string) {
diff --git a/packages/plugin-rsc/examples/source-map/src/features/server-function-name/action.ts b/packages/plugin-rsc/examples/source-map/src/features/server-function-name/action.ts
new file mode 100644
index 000000000..92b4bbb17
--- /dev/null
+++ b/packages/plugin-rsc/examples/source-map/src/features/server-function-name/action.ts
@@ -0,0 +1,5 @@
+'use server'
+
+export async function moduleFunctionName() {
+ return new Error().stack?.split('\n')[1] ?? ''
+}
diff --git a/packages/plugin-rsc/examples/source-map/src/features/server-function-name/server.tsx b/packages/plugin-rsc/examples/source-map/src/features/server-function-name/server.tsx
new file mode 100644
index 000000000..3938164e3
--- /dev/null
+++ b/packages/plugin-rsc/examples/source-map/src/features/server-function-name/server.tsx
@@ -0,0 +1,29 @@
+import { SourceLocationCase } from '../../client'
+import { moduleFunctionName } from './action'
+
+export function ServerFunctionName() {
+ async function inlineFunctionName() {
+ 'use server'
+ return new Error().stack?.split('\n')[1] ?? ''
+ }
+
+ return (
+
+ Server Function names
+
+
+ )
+}
diff --git a/packages/plugin-rsc/examples/source-map/src/root.tsx b/packages/plugin-rsc/examples/source-map/src/root.tsx
index 100141c31..431f7396e 100644
--- a/packages/plugin-rsc/examples/source-map/src/root.tsx
+++ b/packages/plugin-rsc/examples/source-map/src/root.tsx
@@ -6,6 +6,7 @@ import { MultipleExports } from './features/multiple-exports/server'
import { NamedFunction } from './features/named-function/server'
import { ServerActionError } from './features/server-action-error/server'
import { ServerComponentError } from './features/server-component-error/server'
+import { ServerFunctionName } from './features/server-function-name/server'
import { ServerReferenceFromClient } from './features/server-reference-from-client/server'
import { Specifiers } from './features/specifiers/server'
import { TypescriptTsx } from './features/typescript-tsx/server'
@@ -65,6 +66,13 @@ const routes = [
description: 'Two generated registrations from one module.',
render: () => ,
},
+ {
+ path: '/server-function-name',
+ title: 'Server Function names',
+ description:
+ 'Module-level and inline Server Functions preserve their source names in stack traces.',
+ render: () => ,
+ },
{
path: '/server-action-error',
title: 'Server Action error',