vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.89k stars 26.98k forks source link

TypeError: Cannot read property 'toLowerCase' of undefined #22429

Closed binajmen closed 3 years ago

binajmen commented 3 years ago

What version of Next.js are you using?

10.0.7

What version of Node.js are you using?

14.15.5-buster

What browser are you using?

Chrome

What operating system are you using?

Docker image node:14.15.5-buster

How are you deploying your application?

Docker image on Google Cloud Platform using Cloud Run

Describe the Bug

I get the following errors and the page will not load:

$ next start -p $PORT
Loaded env from /app/.env.local
ready - started server on 0.0.0.0:8080, url: http://localhost:8080
(node:24) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'toLowerCase' of undefined
 at /app/node_modules/next/dist/next-server/lib/i18n/normalize-locale-path.js:2:89
 at Array.some (<anonymous>)
 at normalizeLocalePath (/app/node_modules/next/dist/next-server/lib/i18n/normalize-locale-path.js:2:55)
 at Server.handleRequest (/app/node_modules/next/dist/next-server/server/next-server.js:21:274)
 at Server.emit (events.js:315:20)
 at parserOnIncoming (_http_server.js:874:12)
 at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:24) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:24) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:24) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'toLowerCase' of undefined
 at /app/node_modules/next/dist/next-server/lib/i18n/normalize-locale-path.js:2:89
 at Array.some (<anonymous>)
 at normalizeLocalePath (/app/node_modules/next/dist/next-server/lib/i18n/normalize-locale-path.js:2:55)
 at Server.handleRequest (/app/node_modules/next/dist/next-server/server/next-server.js:21:274)
 at Server.emit (events.js:315:20)
 at parserOnIncoming (_http_server.js:874:12)
 at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17)
(node:24) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:24) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'toLowerCase' of undefined
...

Expected Behavior

I expect the page to be loaded.

To Reproduce

I can't provide a github repo as it is a private project, but see below some relevant files that could help.

Relevant files that could help:

// package.json

{
  "name": "---",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p $PORT"
  },
  "dependencies": {
    "@chakra-ui/react": "^1.3.3",
    "@emotion/react": "^11.1.5",
    "@emotion/styled": "^11.1.5",
    "easy-peasy": "^4.0.1",
    "emotion-theming": "^11.0.0",
    "firebase": "^8.2.7",
    "firebase-admin": "^9.5.0",
    "formik": "^2.2.6",
    "framer-motion": "^3.3.0",
    "next": "^10.0.7",
    "next-firebase-auth": "^0.13.0-alpha.0",
    "next-translate": "^1.0.2",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-firebaseui": "^4.1.0",
    "react-icons": "^4.2.0",
    "react-redux": "^7.2.2",
    "yup": "^0.32.9"
  },
  "devDependencies": {
    "@types/node": "^14.14.27",
    "@types/react": "^17.0.2",
    "typescript": "^4.1.5"
  }
}
// next.config.js

const nextTranslate = require('next-translate')

module.exports = nextTranslate()
// .Dockerfile

# base image
FROM node:14.15.5-buster

# working directory
WORKDIR /app

# add binaries to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY package.json /app/
COPY yarn.lock /app/
RUN yarn install

# copy app files and build
COPY . /app
RUN yarn build

# start app
CMD [ "yarn", "start" ]
binajmen commented 3 years ago

I've found out the problem.

In the getServerSideProps, I'm retrieving data from Firestore using the admin SDK. In order to use the emulator in the development environment, you must set the .env variable FIRESTORE_EMULATOR_HOST to connect to the emulator running locally. Unfortunately, it was in my .env.local and therefore pushed in the production Docker image... Therefore the connection was impossible.

Nevertheless, I don't understand why it pops a totally different error, that is: toLowerCase is undefined. Any idea how we could avoid obfuscating these kind of errors?

// pages/index.js
...
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
    try {
        const vendorsRef = admin.firestore().collection('vendors')
        const snapshot = await vendorsRef.get()

        if (snapshot.empty) {
            return { props: { vendors: [] } }
        }

        const docs: any = [] // TOFIX: define type
        snapshot.forEach(doc => {
            const { geopoint, ...rest } = doc.data()
            docs.push({ id: doc.id, ...rest })
        })

        return {
            props: {
                vendors: docs
            }
        }
    } catch (error) {
        console.error(error)
        return { redirect: { destination: '/404', permanent: false } }
    }
}
# FIREBASE ADMIN LOCAL
FIRESTORE_EMULATOR_HOST=localhost:8080 // 👈  this caused the error
#FIREBASE_AUTH_EMULATOR_HOST=localhost:9099
leerob commented 3 years ago

Hey! I'm sorry you had an issue here but glad you found the solution 😄

This does seem like a problem that arose from your codebase, but I agree that error wasn't the most helpful. To be honest, I'm not sure a good way from the framework to detect the issue you presented (I included my .env.local in production) because I'm not sure we could make an assumption that was definitely wrong for someone. We could throw a warning? But I'm not sure.

If you have a suggestion, I'm open. Otherwise, I'll close this one.

binajmen commented 3 years ago

The warning message was misleading, but that's the beauty of code debugging I guess 😅 It's just weird that Firebase is not raising an error prior to this one..

In the end, the solution was to use env.local.development which is clearly documented here.

ahmedyounes commented 3 years ago

I had the same issue and i disabled i18n in next.config to find out that i didnt correctly format my paths in getStaticPaths. i re-enabled i18n in next.config after fixing paths and its working .

balazsorban44 commented 2 years ago

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.