-
Notifications
You must be signed in to change notification settings - Fork 27.8k
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
Display the stitched error instead of react error #72106
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
d2cca05
display stitched error
huozhi 55c6f97
handle cause
huozhi 860a7d1
test: add case for handling invalid element
huozhi b1881d0
do no map react error state
huozhi 10ee3ce
rename test
huozhi eb179cb
fix typo
huozhi a4eaeed
add comparison between owner stack enabled and disabled
huozhi 96e5cc9
update test for ppr
huozhi 7eece64
provide better owner stack example
huozhi 90479c9
update snapshot
huozhi 31d6d97
separate tests
huozhi 23b26b3
fix snapshot
huozhi e7d9d7d
fix indentation
huozhi cd3e147
update comment
huozhi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
test/development/app-dir/owner-stack-invalid-element-type/app/browser/browser-only.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
'use client' | ||
|
||
import Foo from '../foo' | ||
|
||
export default function BrowserOnly() { | ||
return ( | ||
<div> | ||
<Foo /> | ||
</div> | ||
) | ||
} |
16 changes: 16 additions & 0 deletions
16
test/development/app-dir/owner-stack-invalid-element-type/app/browser/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use client' | ||
|
||
import dynamic from 'next/dynamic' | ||
|
||
const BrowserOnly = dynamic(() => import('./browser-only'), { | ||
ssr: false, | ||
}) | ||
|
||
// Intermediate component for testing owner stack | ||
function Inner() { | ||
return <BrowserOnly /> | ||
} | ||
|
||
export default function Page() { | ||
return <Inner /> | ||
} |
Empty file.
8 changes: 8 additions & 0 deletions
8
test/development/app-dir/owner-stack-invalid-element-type/app/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { ReactNode } from 'react' | ||
export default function Root({ children }: { children: ReactNode }) { | ||
return ( | ||
<html> | ||
<body>{children}</body> | ||
</html> | ||
) | ||
} |
14 changes: 14 additions & 0 deletions
14
test/development/app-dir/owner-stack-invalid-element-type/app/rsc/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Foo from '../foo' | ||
|
||
// Intermediate component for testing owner stack | ||
function Inner() { | ||
return <Foo /> | ||
} | ||
|
||
export default function Page() { | ||
return ( | ||
<div> | ||
<Inner /> | ||
</div> | ||
) | ||
} |
16 changes: 16 additions & 0 deletions
16
test/development/app-dir/owner-stack-invalid-element-type/app/ssr/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
'use client' | ||
|
||
import Foo from '../foo' | ||
|
||
// Intermediate component for testing owner stack | ||
function Inner() { | ||
return <Foo /> | ||
} | ||
|
||
export default function Page() { | ||
return ( | ||
<div> | ||
<Inner /> | ||
</div> | ||
) | ||
} |
133 changes: 133 additions & 0 deletions
133
test/development/app-dir/owner-stack-invalid-element-type/invalid-element-type.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
process.env.TEST_OWNER_STACK = 'false' | ||
|
||
import { nextTestSetup } from 'e2e-utils' | ||
import { | ||
assertHasRedbox, | ||
getRedboxSource, | ||
getStackFramesContent, | ||
} from 'next-test-utils' | ||
|
||
// TODO: When owner stack is enabled by default, remove the condition and only keep one test | ||
const isOwnerStackEnabled = | ||
process.env.TEST_OWNER_STACK !== 'false' || | ||
process.env.__NEXT_EXPERIMENTAL_PPR === 'true' | ||
|
||
;(isOwnerStackEnabled ? describe.skip : describe)( | ||
'app-dir - invalid-element-type', | ||
() => { | ||
const { next } = nextTestSetup({ | ||
files: __dirname, | ||
}) | ||
|
||
it('should catch invalid element from a browser only component', async () => { | ||
const browser = await next.browser('/browser') | ||
|
||
await assertHasRedbox(browser) | ||
const source = await getRedboxSource(browser) | ||
|
||
const stackFramesContent = await getStackFramesContent(browser) | ||
if (process.env.TURBOPACK) { | ||
expect(stackFramesContent).toMatchInlineSnapshot(`""`) | ||
expect(source).toMatchInlineSnapshot(` | ||
"app/browser/browser-only.js (8:7) @ BrowserOnly | ||
|
||
6 | return ( | ||
7 | <div> | ||
> 8 | <Foo /> | ||
| ^ | ||
9 | </div> | ||
10 | ) | ||
11 | }" | ||
`) | ||
} else { | ||
expect(stackFramesContent).toMatchInlineSnapshot(`""`) | ||
// FIXME: the methodName should be `@ BrowserOnly` instead of `@ Foo` | ||
expect(source).toMatchInlineSnapshot(` | ||
"app/browser/browser-only.js (8:8) @ Foo | ||
|
||
6 | return ( | ||
7 | <div> | ||
> 8 | <Foo /> | ||
| ^ | ||
9 | </div> | ||
10 | ) | ||
11 | }" | ||
`) | ||
} | ||
}) | ||
|
||
it('should catch invalid element from a rsc component', async () => { | ||
const browser = await next.browser('/rsc') | ||
|
||
await assertHasRedbox(browser) | ||
const stackFramesContent = await getStackFramesContent(browser) | ||
const source = await getRedboxSource(browser) | ||
|
||
if (process.env.TURBOPACK) { | ||
expect(stackFramesContent).toMatchInlineSnapshot(`""`) | ||
expect(source).toMatchInlineSnapshot(` | ||
"app/rsc/page.js (5:10) @ Inner | ||
|
||
3 | // Intermediate component for testing owner stack | ||
4 | function Inner() { | ||
> 5 | return <Foo /> | ||
| ^ | ||
6 | } | ||
7 | | ||
8 | export default function Page() {" | ||
`) | ||
} else { | ||
expect(stackFramesContent).toMatchInlineSnapshot(`""`) | ||
// FIXME: the methodName should be `@ Inner` instead of `@ Foo` | ||
expect(source).toMatchInlineSnapshot(` | ||
"app/rsc/page.js (5:11) @ Foo | ||
|
||
3 | // Intermediate component for testing owner stack | ||
4 | function Inner() { | ||
> 5 | return <Foo /> | ||
| ^ | ||
6 | } | ||
7 | | ||
8 | export default function Page() {" | ||
`) | ||
} | ||
}) | ||
|
||
it('should catch invalid element from on ssr client component', async () => { | ||
const browser = await next.browser('/ssr') | ||
|
||
await assertHasRedbox(browser) | ||
|
||
const stackFramesContent = await getStackFramesContent(browser) | ||
const source = await getRedboxSource(browser) | ||
if (process.env.TURBOPACK) { | ||
expect(stackFramesContent).toMatchInlineSnapshot(`""`) | ||
expect(source).toMatchInlineSnapshot(` | ||
"app/ssr/page.js (7:10) @ Inner | ||
|
||
5 | // Intermediate component for testing owner stack | ||
6 | function Inner() { | ||
> 7 | return <Foo /> | ||
| ^ | ||
8 | } | ||
9 | | ||
10 | export default function Page() {" | ||
`) | ||
} else { | ||
expect(stackFramesContent).toMatchInlineSnapshot(`""`) | ||
// FIXME: the methodName should be `@ Inner` instead of `@ Foo` | ||
expect(source).toMatchInlineSnapshot(` | ||
"app/ssr/page.js (7:11) @ Foo | ||
|
||
5 | // Intermediate component for testing owner stack | ||
6 | function Inner() { | ||
> 7 | return <Foo /> | ||
| ^ | ||
8 | } | ||
9 | | ||
10 | export default function Page() {" | ||
`) | ||
} | ||
}) | ||
} | ||
) |
10 changes: 10 additions & 0 deletions
10
test/development/app-dir/owner-stack-invalid-element-type/next.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* @type {import('next').NextConfig} | ||
*/ | ||
const nextConfig = { | ||
experimental: { | ||
reactOwnerStack: process.env.TEST_OWNER_STACK !== 'false', | ||
}, | ||
} | ||
|
||
module.exports = nextConfig |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This is not used anymore, I didn't figure out last time how to get rid of this. Some tests were failing when I replace
[reactError]
withstate.errors
.This time I found that it's the issue with not reporting
error.cause
inonRecoverableError
, otherwise it's erroring with"There was an error during concurrent rendering but React was able to recover by instead synchronously rendering the entire root."
. The critical change is inonRecoverableError