Skip to content
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

Render a helpful message for null GS(S)P return #14252

Merged
merged 3 commits into from
Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/next/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export const PAGES_404_GET_INITIAL_PROPS_ERROR = `\`pages/404\` can not have get

export const SERVER_PROPS_EXPORT_ERROR = `pages with \`getServerSideProps\` can not be exported. See more info here: https://err.sh/next.js/gssp-export`

export const GSP_NO_RETURNED_VALUE =
'Your `getStaticProps` function did not return an object. Did you forget to add a `return`?'
export const GSSP_NO_RETURNED_VALUE =
'Your `getServerSideProps` function did not return an object. Did you forget to add a `return`?'

export const UNSTABLE_REVALIDATE_RENAME_ERROR =
'The `revalidate` property is not yet available for general use.\n' +
'To try the experimental implementation, please use `unstable_revalidate` instead.\n' +
Expand Down
20 changes: 15 additions & 5 deletions packages/next/next-server/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@ import { IncomingMessage, ServerResponse } from 'http'
import { ParsedUrlQuery } from 'querystring'
import React from 'react'
import { renderToStaticMarkup, renderToString } from 'react-dom/server'
import { UnwrapPromise } from '../../lib/coalesced-function'
import {
GSP_NO_RETURNED_VALUE,
GSSP_COMPONENT_MEMBER_ERROR,
GSSP_NO_RETURNED_VALUE,
PAGES_404_GET_INITIAL_PROPS_ERROR,
SERVER_PROPS_GET_INIT_PROPS_CONFLICT,
SERVER_PROPS_SSG_CONFLICT,
SSG_GET_INITIAL_PROPS_CONFLICT,
UNSTABLE_REVALIDATE_RENAME_ERROR,
GSSP_COMPONENT_MEMBER_ERROR,
} from '../../lib/constants'
import { isSerializableProps } from '../../lib/is-serializable-props'
import { GetServerSideProps, GetStaticProps } from '../../types'
import { isInAmpMode } from '../lib/amp'
import { AmpStateContext } from '../lib/amp-context'
import {
AMP_RENDER_TARGET,
STATIC_PROPS_ID,
SERVER_PROPS_ID,
STATIC_PROPS_ID,
} from '../lib/constants'
import { defaultHead } from '../lib/head'
import { HeadManagerContext } from '../lib/head-manager-context'
import Loadable from '../lib/loadable'
import { LoadableContext } from '../lib/loadable-context'
import { HeadManagerContext } from '../lib/head-manager-context'
import mitt, { MittEmitter } from '../lib/mitt'
import { RouterContext } from '../lib/router-context'
import { NextRouter } from '../lib/router/router'
Expand All @@ -41,8 +45,6 @@ import { tryGetPreviewData, __ApiPreviewProps } from './api-utils'
import { getPageFiles } from './get-page-files'
import { LoadComponentsReturnType, ManifestItem } from './load-components'
import optimizeAmp from './optimize-amp'
import { UnwrapPromise } from '../../lib/coalesced-function'
import { GetStaticProps, GetServerSideProps } from '../../types'

function noRouter() {
const message =
Expand Down Expand Up @@ -515,6 +517,10 @@ export async function renderToHTML(
throw staticPropsError
}

if (data == null) {
throw new Error(GSP_NO_RETURNED_VALUE)
}

const invalidKeys = Object.keys(data).filter(
(key) => key !== 'unstable_revalidate' && key !== 'props'
)
Expand Down Expand Up @@ -601,6 +607,10 @@ export async function renderToHTML(
throw serverSidePropsError
}

if (data == null) {
throw new Error(GSSP_NO_RETURNED_VALUE)
}

const invalidKeys = Object.keys(data).filter((key) => key !== 'props')

if (invalidKeys.length) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/* eslint-env jest */

import fs from 'fs-extra'
import { join } from 'path'
import {
nextBuild,
launchApp,
findPort,
renderViaHTTP,
killApp,
launchApp,
nextBuild,
renderViaHTTP,
} from 'next-test-utils'

import { join } from 'path'
import {
GSP_NO_RETURNED_VALUE,
GSSP_NO_RETURNED_VALUE,
} from '../../../../packages/next/dist/lib/constants'
jest.setTimeout(1000 * 60 * 2)

const appDir = join(__dirname, '..')
Expand Down Expand Up @@ -88,9 +91,37 @@ const runTests = (isDev = false) => {
`getStaticPaths can not be attached to a page's component and must be exported from the page`
)
})

it('should show error for undefined getStaticProps', async () => {
await fs.writeFile(
indexPage,
`
export function getStaticProps() {}
export default function Page() {
return <div />;
}
`
)
expect(await getStderr()).toContain(GSP_NO_RETURNED_VALUE)
})

if (isDev) {
it('should show error for undefined getServerSideProps', async () => {
await fs.writeFile(
indexPage,
`
export function getServerSideProps() {}
export default function Page() {
return <div />;
}
`
)
expect(await getStderr()).toContain(GSSP_NO_RETURNED_VALUE)
})
}
}

describe('GSSP Page Component Member Error', () => {
describe('GS(S)P Page Errors', () => {
beforeAll(async () => {
origIndexPage = await fs.readFile(indexPage, 'utf8')
})
Expand Down