Skip to content

Commit 0708d85

Browse files
committed
[test] Add dedicated test for error when client functions are called from server components
1 parent 0fb4a6d commit 0708d85

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use client'
2+
3+
export function useClient() {
4+
return 'client function'
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Suspense } from 'react'
2+
import { useClient } from './client'
3+
4+
function Component() {
5+
useClient()
6+
7+
return <p>Hello, Dave</p>
8+
}
9+
export default function Page() {
10+
return (
11+
<Suspense>
12+
<Component />
13+
</Suspense>
14+
)
15+
}

test/development/app-dir/source-mapping/source-mapping.test.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { nextTestSetup } from 'e2e-utils'
22
import { retry } from 'next-test-utils'
33

4+
const isCacheComponentsEnabled =
5+
process.env.__NEXT_EXPERIMENTAL_CACHE_COMPONENTS === 'true'
6+
47
describe('source-mapping', () => {
5-
const { next } = nextTestSetup({
8+
const { isTurbopack, next } = nextTestSetup({
69
files: __dirname,
710
})
811

@@ -165,4 +168,41 @@ describe('source-mapping', () => {
165168
)
166169
})
167170
})
171+
172+
it('should show an error when client functions are called from server components', async () => {
173+
const browser = await next.browser('/server-client')
174+
175+
// TODO(veil): Top stack should be ignore-listed
176+
if (isTurbopack) {
177+
await expect(browser).toDisplayRedbox(`
178+
{
179+
"description": "Attempted to call useClient() from the server but useClient is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.",
180+
"environmentLabel": "${isCacheComponentsEnabled ? 'Prerender' : 'Server'}",
181+
"label": "Runtime Error",
182+
"source": "app/server-client/client.js/proxy.mjs (3:24) @ <anonymous>
183+
> 3 | function() { throw new Error("Attempted to call useClient() from the server but useClient is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component."); },
184+
| ^",
185+
"stack": [
186+
"<anonymous> app/server-client/client.js/proxy.mjs (3:24)",
187+
"Component app/server-client/page.js (5:12)",
188+
],
189+
}
190+
`)
191+
} else {
192+
await expect(browser).toDisplayRedbox(`
193+
{
194+
"description": "Attempted to call useClient() from the server but useClient is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.",
195+
"environmentLabel": "${isCacheComponentsEnabled ? 'Prerender' : 'Server'}",
196+
"label": "Runtime Error",
197+
"source": "app/server-client/page.js (5:12) @ Component
198+
> 5 | useClient()
199+
| ^",
200+
"stack": [
201+
"<FIXME-file-protocol>",
202+
"Component app/server-client/page.js (5:12)",
203+
],
204+
}
205+
`)
206+
}
207+
})
168208
})

0 commit comments

Comments
 (0)