diff --git a/errors/invalid-server-options.md b/errors/invalid-server-options.md new file mode 100644 index 0000000000000..b688e53942e8a --- /dev/null +++ b/errors/invalid-server-options.md @@ -0,0 +1,25 @@ +# It looks like the next instance is being instantiated incorrectly. + +#### Why This Error Occurred + +You have passed a null or undefined parameter to the next() call. + +#### Possible Ways to Fix It + +Make sure you are passing the variables properly: + +```js +const app = next() +``` + +And make sure you're passing dev as shown in the examples below: + +```js +const app = next({ dev: boolean }) +``` + +### Useful Links + +- [custom-server-express](https://github.com/vercel/next.js/blob/6ca00bfe312c8d3fc5c20d25a9cd8d2741a29332/examples/custom-server-express/server.js#L6) +- [custom-server](https://github.com/vercel/next.js/blob/6ca00bfe312c8d3fc5c20d25a9cd8d2741a29332/examples/custom-server/server.js#L6) +- [custom-server-typescript](https://github.com/vercel/next.js/blob/6ca00bfe312c8d3fc5c20d25a9cd8d2741a29332/examples/custom-server-typescript/server/index.ts#L7) diff --git a/packages/next/server/next.ts b/packages/next/server/next.ts index 39e98c97e3ec8..6b17c6496c85c 100644 --- a/packages/next/server/next.ts +++ b/packages/next/server/next.ts @@ -13,6 +13,12 @@ type NextServerConstructor = Omit & { function createServer(options: NextServerConstructor): Server { const standardEnv = ['production', 'development', 'test'] + if (options == null) { + throw new Error( + 'The server has not been instantiated properly. https://err.sh/next.js/invalid-server-options' + ) + } + if ( !(options as any).isNextDevCommand && process.env.NODE_ENV && @@ -22,6 +28,12 @@ function createServer(options: NextServerConstructor): Server { } if (options.dev) { + if (typeof options.dev !== 'boolean') { + console.warn( + "Warning: 'dev' is not a boolean which could introduce unexpected behavior. https://err.sh/next.js/invalid-server-options" + ) + } + const DevServer = require('./next-dev-server').default return new DevServer(options) } diff --git a/test/integration/invalid-server-options/pages/index.js b/test/integration/invalid-server-options/pages/index.js new file mode 100644 index 0000000000000..f40492ac06d85 --- /dev/null +++ b/test/integration/invalid-server-options/pages/index.js @@ -0,0 +1 @@ +export default () => 'test' diff --git a/test/integration/invalid-server-options/test/index.test.js b/test/integration/invalid-server-options/test/index.test.js new file mode 100644 index 0000000000000..9137fffdb31db --- /dev/null +++ b/test/integration/invalid-server-options/test/index.test.js @@ -0,0 +1,65 @@ +import next from 'next' +import { join } from 'path' +const dir = join(__dirname, '../') +const warningMessage = + "Warning: 'dev' is not a boolean which could introduce unexpected behavior. https://err.sh/next.js/invalid-server-options" + +describe('Invalid server options', () => { + test('next() called with no parameters should throw error', () => { + expect(() => next()).toThrowError( + 'The server has not been instantiated properly. https://err.sh/next.js/invalid-server-options' + ) + }) + + test('next() called with undefined parameter should throw error', () => { + expect(() => next(undefined)).toThrowError( + 'The server has not been instantiated properly. https://err.sh/next.js/invalid-server-options' + ) + }) + + test('next() called with null parameter should throw error', () => { + expect(() => next(null)).toThrowError( + 'The server has not been instantiated properly. https://err.sh/next.js/invalid-server-options' + ) + }) + + test('next() called with dev as string should send warning', () => { + const consoleSpy = jest.spyOn(console, 'warn') + const dev = 'string' + next({ dev, dir }) + + expect(consoleSpy).toHaveBeenCalledWith(warningMessage) + }) + + test('next() called with dev as number should send warning', () => { + const consoleSpy = jest.spyOn(console, 'warn') + const dev = 123 + next({ dev, dir }) + + expect(consoleSpy).toHaveBeenCalledWith(warningMessage) + }) + + test('next() called with dev as array should send warning', () => { + const consoleSpy = jest.spyOn(console, 'warn') + const dev = ['array'] + next({ dev, dir }) + + expect(consoleSpy).toHaveBeenCalledWith(warningMessage) + }) + + test('next() called with dev as object should send warning', () => { + const consoleSpy = jest.spyOn(console, 'warn') + const dev = { test: 'goes here' } + next({ dev, dir }) + + expect(consoleSpy).toHaveBeenCalledWith(warningMessage) + }) + + test('next() called with dev as function should send warning', () => { + const consoleSpy = jest.spyOn(console, 'warn') + const dev = () => console.log('test') + next({ dev, dir }) + + expect(consoleSpy).toHaveBeenCalledWith(warningMessage) + }) +})