-
Notifications
You must be signed in to change notification settings - Fork 31.2k
test(instant-validation): document usePathname() stack-trace attribution today #94422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: canary
Are you sure you want to change the base?
Changes from 3 commits
08b7e6c
73ba110
d7285c6
3e310c5
18567a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| 'use client' | ||
|
|
||
| import { PathnameReader } from './pathname-reader' | ||
|
|
||
| export function InnerWrapper() { | ||
| return ( | ||
| <p> | ||
| Current path: <PathnameReader /> | ||
| </p> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| 'use client' | ||
|
|
||
| import { InnerWrapper } from './inner-wrapper' | ||
|
|
||
| export function MiddleWrapper() { | ||
| return ( | ||
| <div> | ||
| <InnerWrapper /> | ||
| </div> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| 'use client' | ||
|
|
||
| import { MiddleWrapper } from './middle-wrapper' | ||
|
|
||
| export function OuterWrapper() { | ||
| return ( | ||
| <section> | ||
| <MiddleWrapper /> | ||
| </section> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import type { Instant } from 'next' | ||
| import { OuterWrapper } from './outer-wrapper' | ||
|
|
||
| export const unstable_instant: Instant = { | ||
| level: 'experimental-error', | ||
| unstable_samples: [ | ||
| { | ||
| params: { | ||
| one: '123', | ||
| // two: <missing> | ||
| }, | ||
| }, | ||
| ], | ||
| } | ||
|
|
||
| export default function Page() { | ||
| return ( | ||
| <main> | ||
| <p> | ||
| usePathname() nested three wrappers deep should still point at the | ||
| actual call site. | ||
| </p> | ||
| <OuterWrapper /> | ||
| </main> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| 'use client' | ||
|
|
||
| import { usePathname } from 'next/navigation' | ||
|
|
||
| export function PathnameReader() { | ||
| const pathname = usePathname() | ||
| return <span data-testid="pathname">{pathname}</span> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import type { Instant } from 'next' | ||
| import { PathnameReader } from './pathname-reader' | ||
|
|
||
| export const unstable_instant: Instant = { | ||
| level: 'experimental-error', | ||
| unstable_samples: [ | ||
| { | ||
| params: { | ||
| one: '123', | ||
| // two: <missing> | ||
| }, | ||
| }, | ||
| ], | ||
| } | ||
|
|
||
| export default function Page() { | ||
| return ( | ||
| <main> | ||
| <p> | ||
| usePathname() without an ensureThrows wrapper should point at the call | ||
| site in the user's source. | ||
| </p> | ||
| <PathnameReader /> | ||
| </main> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| 'use client' | ||
|
|
||
| import { usePathname } from 'next/navigation' | ||
|
|
||
| export function PathnameReader() { | ||
| const pathname = usePathname() | ||
| return <span data-testid="pathname">{pathname}</span> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { PathnameLabel } from './pathname-label' | ||
|
|
||
| export default function Page() { | ||
| return ( | ||
| <main> | ||
| <PathnameLabel /> | ||
| </main> | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| 'use client' | ||
|
|
||
| import { usePathname } from 'next/navigation' | ||
|
|
||
| export function PathnameLabel() { | ||
| const pathname = usePathname() | ||
| return <span data-testid="pathname-label">{pathname}</span> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1893,6 +1893,37 @@ describe('instant validation', () => { | |
| expectNoBuildValidationErrors(result) | ||
| } | ||
| }) | ||
|
|
||
| // Today the dev overlay misattributes usePathname() errors to the | ||
| // parent's JSX line instead of the actual hook call site. When the | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI this is a React decision. Error stacks have less fidelity in production for performance reasons.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thats what i learned, but @gnoff has a PR to change that i think?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| // URL-hook factory lands, this test will start passing and | ||
| // `it.failing` will itself fail — flip it back to `it`. | ||
| /* eslint-disable jest/no-standalone-expect */ | ||
| ;(isNextDev && !isClientNav ? it.failing : it)( | ||
| 'invalid - usePathname() in a client component on a route with a fallback param', | ||
| async () => { | ||
| if (!isNextDev || isClientNav) { | ||
| return | ||
| } | ||
| const browser = await navigateTo( | ||
| '/default/invalid-use-pathname-no-samples/123' | ||
| ) | ||
| await expect(browser).toDisplayCollapsedRedbox(` | ||
| { | ||
| "description": "Next.js encountered uncached data during prerendering.", | ||
| "environmentLabel": "Server", | ||
| "label": "Blocking Route", | ||
| "source": "app/default/invalid-use-pathname-no-samples/[slug]/pathname-label.tsx (6:20) @ PathnameLabel | ||
| > 6 | const pathname = usePathname() | ||
| | ^", | ||
| "stack": [ | ||
| "PathnameLabel app/default/invalid-use-pathname-no-samples/[slug]/pathname-label.tsx (6:20)", | ||
| ], | ||
| } | ||
| `) | ||
| } | ||
| ) | ||
| /* eslint-enable jest/no-standalone-expect */ | ||
| }) | ||
|
|
||
| describe('client errors', () => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That doesn't really tell us stack attribution is working because it's just the sync error from misuing samples. The codeframe is the one we finally want. But it's broken at the moment.