Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1a4a3a7

Browse files
GatsbyJS BotLekoArts
GatsbyJS Bot
andauthoredMay 11, 2021
feat(gatsby): New overlay for DEV_SSR (#31061) (#31361)
Co-authored-by: gatsbybot <mathews.kyle+gatsbybot@gmail.com> Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com> (cherry picked from commit 7110189) Co-authored-by: Lennart <lekoarts@gmail.com>

File tree

22 files changed

+400
-549
lines changed

22 files changed

+400
-549
lines changed
 

‎e2e-tests/development-runtime/cypress/integration/navigation/redirect.js

+32-22
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,38 @@ Cypress.on(`window:before:load`, win => {
55

66
const runTests = () => {
77
it(`should redirect page to index page when there is no such page`, () => {
8-
cy.visit(`/redirect-without-page`).waitForRouteChange()
8+
cy.visit(`/redirect-without-page`, {
9+
failOnStatusCode: false,
10+
}).waitForRouteChange()
911

1012
cy.location(`pathname`).should(`equal`, `/`)
1113
cy.then(() => {
1214
const calls = spy.getCalls()
1315

14-
const callsAboutRedirectMatchingPage = calls.filter(call => {
15-
return call.args[0].includes(
16-
"matches both a page and a redirect; this is probably not intentional."
16+
const callsAboutRedirectMatchingPage = calls.filter(call =>
17+
call.args[0].includes(
18+
`matches both a page and a redirect; this is probably not intentional.`
1719
)
18-
})
20+
)
1921

2022
expect(callsAboutRedirectMatchingPage.length).to.equal(0)
2123
})
2224
})
2325

2426
it(`should redirect page to index page even there is a such page`, () => {
25-
cy.visit(`/redirect`).waitForRouteChange()
27+
cy.visit(`/redirect`, {
28+
failOnStatusCode: false,
29+
}).waitForRouteChange()
2630

2731
cy.location(`pathname`).should(`equal`, `/`)
2832
cy.then(() => {
2933
const calls = spy.getCalls()
3034

31-
const callsAboutRedirectMatchingPage = calls.filter(call => {
32-
return call.args[0].includes(
33-
"matches both a page and a redirect; this is probably not intentional."
35+
const callsAboutRedirectMatchingPage = calls.filter(call =>
36+
call.args[0].includes(
37+
`matches both a page and a redirect; this is probably not intentional.`
3438
)
35-
})
39+
)
3640

3741
expect(callsAboutRedirectMatchingPage.length).not.to.equal(0)
3842
expect(spy).to.be.calledWith(
@@ -42,43 +46,47 @@ const runTests = () => {
4246
})
4347

4448
it(`should redirect to a dynamically-created replacement page`, () => {
45-
cy.visit(`/redirect-me/`).waitForRouteChange()
49+
cy.visit(`/redirect-me/`, {
50+
failOnStatusCode: false,
51+
}).waitForRouteChange()
4652

4753
cy.location(`pathname`).should(`equal`, `/pt/redirect-me/`)
4854
cy.then(() => {
4955
expect(spy).not.to.be.calledWith(
5056
`The route "/redirect" matches both a page and a redirect; this is probably not intentional.`
5157
)
5258

53-
cy.findByText("This should be at /pt/redirect-me/", {
59+
cy.findByText(`This should be at /pt/redirect-me/`, {
5460
exact: false,
5561
}).should(`exist`)
5662
})
5763
})
5864
}
5965

6066
describe(`redirect`, () => {
61-
describe("404 is present", () => {
67+
describe(`404 is present`, () => {
6268
before(() => {
6369
cy.task(`restoreAllBlockedResources`)
6470
})
6571

6672
// this is sanity check for this group
6773
it(`make sure 404 is present`, () => {
68-
cy.visit(`/______not_existing_page`).waitForRouteChange()
69-
cy.findByText("Preview custom 404 page").click()
70-
cy.findByText("A custom 404 page wasn't detected", {
74+
cy.visit(`/______not_existing_page`, {
75+
failOnStatusCode: false,
76+
}).waitForRouteChange()
77+
cy.findByText(`Preview custom 404 page`).click()
78+
cy.findByText(`A custom 404 page wasn't detected`, {
7179
exact: false,
7280
}).should(`not.exist`)
7381
cy.findByText(
74-
"You just hit a route that does not exist... the sadness."
82+
`You just hit a route that does not exist... the sadness.`
7583
).should(`exist`)
7684
})
7785

7886
runTests()
7987
})
8088

81-
describe("no 404", () => {
89+
describe(`no 404`, () => {
8290
before(() => {
8391
cy.task(`restoreAllBlockedResources`)
8492

@@ -100,13 +108,15 @@ describe(`redirect`, () => {
100108
})
101109

102110
it(`make sure 404 is NOT present`, () => {
103-
cy.visit(`/______not_existing_page`).waitForRouteChange()
104-
cy.findByText("Preview custom 404 page").click()
105-
cy.findByText("A custom 404 page wasn't detected", {
111+
cy.visit(`/______not_existing_page`, {
112+
failOnStatusCode: false,
113+
}).waitForRouteChange()
114+
cy.findByText(`Preview custom 404 page`).click()
115+
cy.findByText(`A custom 404 page wasn't detected`, {
106116
exact: false,
107117
}).should(`exist`)
108118
cy.findByText(
109-
"You just hit a route that does not exist... the sadness.",
119+
`You just hit a route that does not exist... the sadness.`,
110120
{ exact: false }
111121
).should(`not.exist`)
112122
})

‎e2e-tests/development-runtime/cypress/integration/page-not-found/404.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
describe(`page not found`, () => {
22
beforeEach(() => {
3-
cy.visit(`/__404__`)
3+
cy.visit(`/__404__`, {
4+
failOnStatusCode: false,
5+
})
46
})
57
it(`should display message `, () => {
68
cy.get(`h1`).invoke(`text`).should(`eq`, `Gatsby.js development 404 page`)

‎integration-tests/ssr/__tests__/__snapshots__/ssr.js.snap

+11-130
Original file line numberDiff line numberDiff line change
@@ -3,134 +3,15 @@
33
exports[`SSR is run for a page when it is requested 1`] = `"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><link data-identity=\\"gatsby-dev-css\\" rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"/commons.css\\"/><meta name=\\"note\\" content=\\"environment=development\\"/><script src=\\"/socket.io/socket.io.js\\"></script></head><body><div id=\\"___gatsby\\"><div style=\\"outline:none\\" tabindex=\\"-1\\" id=\\"gatsby-focus-wrapper\\"><div><h1 class=\\"hi\\">Hello world</h1></div></div><div id=\\"gatsby-announcer\\" style=\\"position:absolute;top:0;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0\\" aria-live=\\"assertive\\" aria-atomic=\\"true\\"></div></div><script src=\\"/polyfill.js\\" nomodule=\\"\\"></script><script src=\\"/framework.js\\"></script><script src=\\"/commons.js\\"></script></body></html>"`;
44

55
exports[`SSR it generates an error page correctly 1`] = `
6-
"<head>
7-
<title>Develop SSR Error</title>
8-
<style>
9-
* {
10-
--gatsby: #663399;
11-
--gatsbyLight: #9158ca;
12-
--dimmedWhite: rgba(255, 255, 255, 0.8);
13-
--white: #ffffff;
14-
--black: #000000;
15-
--color-ansi-selection: rgba(95, 126, 151, 0.48);
16-
--color-ansi-bg: #fafafa;
17-
--color-ansi-fg: #545454;
18-
--color-ansi-white: #969896;
19-
--color-ansi-black: #141414;
20-
--color-ansi-blue: #183691;
21-
--color-ansi-cyan: #007faa;
22-
--color-ansi-green: #008000;
23-
--color-ansi-magenta: #795da3;
24-
--color-ansi-red: #d91e18;
25-
--color-ansi-yellow: #aa5d00;
26-
--color-ansi-bright-white: #ffffff;
27-
--color-ansi-bright-black: #545454;
28-
--color-ansi-bright-blue: #183691;
29-
--color-ansi-bright-cyan: #007faa;
30-
--color-ansi-bright-green: #008000;
31-
--color-ansi-bright-magenta: #795da3;
32-
--color-ansi-bright-red: #d91e18;
33-
--color-ansi-bright-yellow: #aa5d00;
34-
--radii: 5px;
35-
--z-index-normal: 5;
36-
--z-index-elevated: 10;
37-
--space: 1.5em;
38-
--space-sm: 1em;
39-
--space-lg: 2.5em;
40-
}
41-
[data-gatsby-overlay=\\"backdrop\\"] {
42-
background: rgba(72, 67, 79, 0.5);
43-
position: absolute;
44-
top: 0;
45-
left: 0;
46-
right: 0;
47-
bottom: 0;
48-
height: 100%;
49-
width: 100%;
50-
z-index: var(--z-index-normal);
51-
backdrop-filter: blur(10px);
52-
}
53-
body {
54-
font: 18px/1.5 -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto,
55-
Helvetica, Arial, sans-serif, \\"Apple Color Emoji\\", \\"Segoe UI Emoji\\",
56-
\\"Segoe UI Symbol\\" !important;
57-
background: var(--color-ansi-bright-white);
58-
padding: var(--space);
59-
overflow: auto;
60-
}
61-
h1,
62-
h2,
63-
h3 {
64-
display: flex;
65-
align-items: center;
66-
color: var(--dimmedWhite);
67-
background: var(--gatsby);
68-
padding: var(--space);
69-
border-top-left-radius: var(--radii);
70-
border-top-right-radius: var(--radii);
71-
}
72-
code {
73-
font-family: Consolas, \\"Andale Mono WT\\", \\"Andale Mono\\", \\"Lucida Console\\", \\"Lucida Sans Typewriter\\", \\"DejaVu Sans Mono\\", \\"Bitstream Vera Sans Mono\\", \\"Liberation Mono\\", \\"Nimbus Mono L\\", Monaco, \\"Courier New\\", Courier, monospace;
74-
}
75-
pre {
76-
margin: 0;
77-
color: var(--color-ansi-fg);
78-
padding: var(--space-sm);
79-
border-radius: var(--radii);
80-
}
81-
button {
82-
cursor: pointer;
83-
border: 1px;
84-
padding: 10px;
85-
background-color: var(--gatsbyLight);
86-
color: var(--white);
87-
appearance: none;
88-
display: inline-flex;
89-
align-items: center;
90-
justify-content: center;
91-
border-radius: var(--radii);
92-
}
93-
</style>
94-
</head>
95-
<h1>Error</h1>
96-
<h2>The page didn't server render (SSR) correctly</h2>
97-
<p style=\\"padding-left: var(--space-sm);\\">
98-
React components in Gatsby must render successfully in the browser and in a
99-
node.js environment. When we tried to render your page component in
100-
node.js, it errored.
101-
</p>
102-
<ul>
103-
<li><strong>URL path:</strong> <code>/bad-page/</code></li>
104-
<li><strong>File path:</strong> <code>src/pages/bad-page.js</code></li>
105-
</ul>
106-
<h3>error</h3>
107-
<code style=\\"padding: var(--space);padding-left: var(--space-sm);\\">window is not defined</code>
108-
<pre><span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"> <span style=\\"color:#527713;\\"> 2 |</span></span>
109-
<span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"> <span style=\\"color:#527713;\\"> 3 |</span> <span style=\\"color:#006500;\\">const</span> <span style=\\"color:#DB3A00;\\">Component</span> <span style=\\"color:#DB3A00;\\">=</span> () <span style=\\"color:#DB3A00;\\">=></span> {</span>
110-
<span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"><span style=\\"color:#096fb3;\\"><span style=\\"font-weight:bold;\\">></span></span><span style=\\"color:#527713;\\"> 4 |</span> <span style=\\"color:#006500;\\">const</span> a <span style=\\"color:#DB3A00;\\">=</span> window<span style=\\"color:#DB3A00;\\">.</span>width</span>
111-
<span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"> <span style=\\"color:#527713;\\"> |</span> <span style=\\"color:#096fb3;\\"><span style=\\"font-weight:bold;\\">^</span></span></span>
112-
<span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"> <span style=\\"color:#527713;\\"> 5 |</span></span>
113-
<span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"> <span style=\\"color:#527713;\\"> 6 |</span> <span style=\\"color:#006500;\\">return</span> <span style=\\"color:#DB3A00;\\"><</span><span style=\\"color:#DB3A00;\\">div</span><span style=\\"color:#DB3A00;\\">></span>hi<span style=\\"color:#DB3A00;\\"><</span><span style=\\"color:#DB3A00;\\">/</span><span style=\\"color:#DB3A00;\\">div</span><span style=\\"color:#DB3A00;\\">></span></span>
114-
<span style=\\"font-weight:normal;opacity:1;color:#452475;background:#ffffff;\\"> <span style=\\"color:#527713;\\"> 7 |</span> }</span></pre>
115-
<p>For help debugging SSR errors, see this docs page: <a
116-
href=\\"https://www.gatsbyjs.com/docs/debugging-html-builds/\\">https://www.gatsbyjs.com/docs/debugging-html-builds/</a></p>
117-
<h3>Skip SSR</h3>
118-
<p style=\\"padding-left: var(--space-sm);\\">
119-
If you don't wish to fix the SSR error at the moment, press the
120-
button below to reload the page without attempting SSR</p>
121-
<p style=\\"padding-left: var(--space-sm);\\">
122-
<strong>Note</strong>: this error will show up in when you build your site so must be fixed before then.</p>
123-
<p style=\\"padding-left: var(--space-sm);\\">
124-
<strong>Caveat</strong>: SSR errors in module scope i.e. outside of your components can't be skipped so will need fixed before you can continue</p>
125-
<button style=\\"margin-left: var(--space-sm);\\" onclick='refreshWithQueryString()'>Skip SSR</button>
126-
<script>
127-
function refreshWithQueryString() {
128-
if ('URLSearchParams' in window) {
129-
var searchParams = new URLSearchParams(window.location.search);
130-
searchParams.set(\\"skip-ssr\\", \\"true\\");
131-
window.location.search = searchParams.toString();
132-
}
133-
}
134-
</script>
135-
"
6+
"<!DOCTYPE html><html><head><meta charSet=\\"utf-8\\"/><meta http-equiv=\\"x-ua-compatible\\" content=\\"ie=edge\\"/><meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, shrink-to-fit=no\\"/><link data-identity=\\"gatsby-dev-css\\" rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"/commons.css\\"/><meta name=\\"note\\" content=\\"environment=development\\"/><script src=\\"/socket.io/socket.io.js\\"></script></head><body><div id=\\"___gatsby\\"><div style=\\"outline:none\\" tabindex=\\"-1\\" id=\\"gatsby-focus-wrapper\\"></div><div id=\\"gatsby-announcer\\" style=\\"position:absolute;top:0;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0\\" aria-live=\\"assertive\\" aria-atomic=\\"true\\"></div></div><script>window._gatsbyEvents = window._gatsbyEvents || []; window._gatsbyEvents.push([\\"FAST_REFRESH\\", { action: \\"SHOW_DEV_SSR_ERROR\\", payload: {\\"codeFrame\\":\\" 2 |/n 3 | const Component = () => {/n> 4 | const a = window.width/n | ^/n 5 |/n 6 | return <div>hi</div>/n 7 | }\\",\\"source\\":\\"src/pages/bad-page.js\\",\\"line\\":4,\\"column\\":13,\\"sourceMessage\\":\\"window is not defined\\",\\"stack\\":\\"ReferenceError: window is not defined/n at Component (<PROJECT_ROOT>/public/webpack:/ssr/src/pages/bad-page.js:4:13)/n at d (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:498)/n at $a (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:39:16)/n at a.b.render (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:476)/n at a.b.read (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:18)/n at renderToString (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:54:364)/n at generateBodyHTML (<PROJECT_ROOT>/public/webpack:/ssr/.cache/ssr-develop-static-entry.js:293:34)/n at Object.__WEBPACK_DEFAULT_EXPORT__ [as default] (<PROJECT_ROOT>/public/webpack:/ssr/.cache/ssr-develop-static-entry.js:323:19)/n at <PROJECT_ROOT>/node_modules/gatsby/src/utils/dev-ssr/render-dev-html-child.js:95:9/n at new Promise (<anonymous>)\\"} }])</script><noscript><h1>Failed to Server Render (SSR)</h1><h2>Error message:</h2><p>window is not defined</p><h2>File:</h2><p>src/pages/bad-page.js:4:13</p><h2>Stack:</h2><pre><code>ReferenceError: window is not defined
7+
at Component (<PROJECT_ROOT>/public/webpack:/ssr/src/pages/bad-page.js:4:13)
8+
at d (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:498)
9+
at $a (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:39:16)
10+
at a.b.render (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:476)
11+
at a.b.read (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:18)
12+
at renderToString (<PROJECT_ROOT>/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:54:364)
13+
at generateBodyHTML (<PROJECT_ROOT>/public/webpack:/ssr/.cache/ssr-develop-static-entry.js:293:34)
14+
at Object.__WEBPACK_DEFAULT_EXPORT__ [as default] (<PROJECT_ROOT>/public/webpack:/ssr/.cache/ssr-develop-static-entry.js:323:19)
15+
at <PROJECT_ROOT>/node_modules/gatsby/src/utils/dev-ssr/render-dev-html-child.js:95:9
16+
at new Promise (&lt;anonymous&gt;)</code></pre></noscript><script src=\\"/polyfill.js\\" nomodule=\\"\\"></script><script src=\\"/framework.js\\"></script><script src=\\"/commons.js\\"></script></body></html>"
13617
`;

‎integration-tests/ssr/__tests__/ssr.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe(`SSR`, () => {
3838
const pageUrl = `http://localhost:8000/bad-page/`
3939
// Poll until the new page is bundled (so starts returning a non-404 status).
4040
const rawDevHtml = await fetchUntil(pageUrl, res => {
41-
return res.status === 500
41+
return res
4242
}).then(res => res.text())
4343
expect(rawDevHtml).toMatchSnapshot()
4444
await fs.remove(dest)

‎integration-tests/ssr/jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
2+
snapshotSerializers: [`jest-serializer-path`],
23
testPathIgnorePatterns: [
34
`/node_modules/`,
45
`__tests__/fixtures`,

‎integration-tests/ssr/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"fs-extra": "^9.0.0",
1919
"jest": "^24.0.0",
2020
"jest-diff": "^24.0.0",
21+
"jest-serializer-path": "^0.1.15",
2122
"npm-run-all": "4.1.5",
2223
"start-server-and-test": "^1.11.3"
2324
},
@@ -30,7 +31,7 @@
3031
"scripts": {
3132
"build": "gatsby build",
3233
"clean": "gatsby clean",
33-
"develop": "cross-env GATSBY_EXPERIMENTAL_DEV_SSR=true gatsby develop",
34+
"develop": "cross-env GATSBY_EXPERIMENTAL_DEV_SSR=true CI=1 FORCE_COLOR=0 gatsby develop",
3435
"serve": "gatsby serve",
3536
"start-dev-server": "start-server-and-test develop http://localhost:8000 test:jest",
3637
"test": "cross-env GATSBY_EXPERIMENTAL_DEV_SSR=true npm-run-all -s build start-dev-server",

‎packages/gatsby-cli/src/structured-errors/error-map.ts

+22-11
Original file line numberDiff line numberDiff line change
@@ -549,18 +549,29 @@ const errors = {
549549
docsUrl: `https://www.gatsbyjs.com/docs/reference/gatsby-cli#new`,
550550
},
551551
"11614": {
552-
text: ({
553-
path,
554-
filePath,
555-
line,
556-
column,
557-
}): string => `The path "${path}" errored during SSR.
558-
559-
Edit its component ${filePath}${
560-
line ? `:${line}:${column}` : ``
561-
} to resolve the error.`,
552+
text: (context): string =>
553+
stripIndent(`
554+
The path "${context.path}" errored during SSR.
555+
Edit its component ${context.filePath}${
556+
context.line ? `:${context.line}:${context.column}` : ``
557+
} to resolve the error.`),
562558
level: Level.WARNING,
563-
docsUrl: `https://gatsby.dev/debug-html`,
559+
},
560+
"11615": {
561+
text: (context): string =>
562+
stripIndent(`
563+
There was an error while trying to load dev-404-page:
564+
${context.sourceMessage}`),
565+
level: Level.ERROR,
566+
category: ErrorCategory.SYSTEM,
567+
},
568+
"11616": {
569+
text: (context): string =>
570+
stripIndent(`
571+
There was an error while trying to create the client-only shell for displaying SSR errors:
572+
${context.sourceMessage}`),
573+
level: Level.ERROR,
574+
category: ErrorCategory.SYSTEM,
564575
},
565576
// Watchdog
566577
"11701": {

0 commit comments

Comments
 (0)
Please sign in to comment.