node.js - Sequelize-CLI、Postgres、Heroku 生产 TypeError [ERR_INVALID_ARG_TYPE] : The "url" argument must be of type string. 接收类型未定义

标签 node.js postgresql heroku sequelize.js

我已经被这个错误困住了几天,所以我在这里寻找一些见解。我有一个 PERN 堆栈应用程序,我第一次尝试将其部署到 Heroku。我的应用程序看起来很好。我的应用程序在本地开发中运行得非常好。我可以运行它来提供来自 react build 的静态文件,我可以在两个端口上运行前端和后端,它可以工作。我认为这个问题与 Sequelize-CLI 如何尝试解析 Heroku 在生产中设置的 DATABASE_URL 配置变量有关。如果我记录 process.env.DATABASE_URL,我会从 Heroku 获得 URI 字符串(在下面的错误堆栈中注明)。

  • 我确保 PG 附加组件配置正确。
  • 我在 .env 文件和 heroku 仪表板中都设置了所有配置变量
  • 我的 node_modules, .env 文件没有提交到我的仓库。
  • 我已经删除了我的 node_modules 和 package-lock.json 并重新安装了它们
  • 我已经注销了 process.env.DATABASE_URL 并且它成功地记录了 URI

  • 我不断收到此错误堆栈:
    enter code here2020-07-19T00:56:44.000000+00:00 app[api]: Build succeeded
    2020-07-19T00:57:10.671364+00:00 heroku[web.1]: Starting process with command `npm start`
    2020-07-19T00:57:14.245382+00:00 app[web.1]: 
    2020-07-19T00:57:14.245410+00:00 app[web.1]: > locals@1.0.0 start /app
    2020-07-19T00:57:14.245411+00:00 app[web.1]: > node server.js
    2020-07-19T00:57:14.245411+00:00 app[web.1]: 
    
    // this is the console.log(process.env.DATABASE_URL)
    2020-07-19T01:09:25.213184+00:00 app[web.1]: postgres://<user>:<password><omitted-info>:<port>/<app>
    
    2020-07-19T00:57:14.903836+00:00 app[web.1]: internal/validators.js:107
    2020-07-19T00:57:14.903838+00:00 app[web.1]: throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
    2020-07-19T00:57:14.903839+00:00 app[web.1]: ^
    2020-07-19T00:57:14.903839+00:00 app[web.1]: 
    2020-07-19T00:57:14.903841+00:00 app[web.1]: TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received type undefined
    2020-07-19T00:57:14.903841+00:00 app[web.1]: at validateString (internal/validators.js:107:11)
    2020-07-19T00:57:14.903841+00:00 app[web.1]: at Url.parse (url.js:155:3)
    2020-07-19T00:57:14.903842+00:00 app[web.1]: at Object.urlParse [as parse] (url.js:150:13)
    2020-07-19T00:57:14.903843+00:00 app[web.1]: at new Sequelize (/app/node_modules/sequelize/lib/sequelize.js:187:28)
    2020-07-19T00:57:14.903843+00:00 app[web.1]: at Object.<anonymous> (/app/models/index.js:14:15)
    2020-07-19T00:57:14.903844+00:00 app[web.1]: at Module._compile (internal/modules/cjs/loader.js:759:30)
    2020-07-19T00:57:14.903844+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    2020-07-19T00:57:14.903845+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:628:32)
    2020-07-19T00:57:14.903845+00:00 app[web.1]: at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    2020-07-19T00:57:14.903845+00:00 app[web.1]: at Module.require (internal/modules/cjs/loader.js:666:19)
    2020-07-19T00:57:14.903846+00:00 app[web.1]: at require (internal/modules/cjs/helpers.js:16:16)
    2020-07-19T00:57:14.903846+00:00 app[web.1]: at Object.<anonymous> (/app/server.js:11:16)
    2020-07-19T00:57:14.903847+00:00 app[web.1]: at Module._compile (internal/modules/cjs/loader.js:759:30)
    2020-07-19T00:57:14.903847+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    2020-07-19T00:57:14.903847+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:628:32)
    2020-07-19T00:57:14.903848+00:00 app[web.1]: at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    2020-07-19T00:57:14.903848+00:00 app[web.1]: at Function.Module.runMain (internal/modules/cjs/loader.js:826:10)
    2020-07-19T00:57:14.903849+00:00 app[web.1]: at internal/main/run_main_module.js:17:11
    2020-07-19T00:57:14.915610+00:00 app[web.1]: npm ERR! code ELIFECYCLE
    2020-07-19T00:57:14.916028+00:00 app[web.1]: npm ERR! errno 1
    2020-07-19T00:57:14.917598+00:00 app[web.1]: npm ERR! locals@1.0.0 start: `node server.js`
    2020-07-19T00:57:14.917834+00:00 app[web.1]: npm ERR! Exit status 1
    2020-07-19T00:57:14.918113+00:00 app[web.1]: npm ERR!
    2020-07-19T00:57:14.918349+00:00 app[web.1]: npm ERR! Failed at the locals@1.0.0 start script.
    2020-07-19T00:57:14.918598+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    2020-07-19T00:57:14.952443+00:00 app[web.1]: 
    2020-07-19T00:57:14.952709+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
    2020-07-19T00:57:14.952798+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2020-07-19T00_57_14_920Z-debug.log
    2020-07-19T00:57:15.047526+00:00 heroku[web.1]: Process exited with status 1
    2020-07-19T00:57:15.094041+00:00 heroku[web.1]: State changed from starting to crashed
    2020-07-19T00:57:15.951511+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=locals-deploy.herokuapp.com request_id=f27a1f1b-5d62-4d98-9383-6d5e46242789 fwd="71.92.89.136" dyno= connect= service= status=503 bytes= protocol=https
    
    现在,如果我尝试在生产模式下在 heroku 上运行 db:migrate ,我会收到关于 URL 的另一个错误。
    heroku run sequelize db:migrate --env production --app locals-deploy
    
    错误:
    Running sequelize db:migrate on ⬢ locals-deploy... up, run.7436 (Free)
    
    Sequelize CLI [Node: 12.0.0, CLI: 5.5.1, ORM: 5.22.3]
    
    Loaded configuration file "config/config.js".
    Using environment "production".
    
    ERROR: Error parsing url: undefined
    
    package.json
    
    {
      "name": "locals",
      "version": "1.0.0",
      "description": "A place for travelers to meet locals.",
      "main": "server.js",
      "scripts": {
        "start": "node server.js",
        "heroku-postbuild": "cd client && npm install && npm run build"
      },
      "author": "Name Name",
      "license": "MIT",
      "dependencies": {
        "axios": "^0.19.2",
        "bcryptjs": "^2.4.3",
        "body-parser": "^1.19.0",
        "cloudinary": "^1.22.0",
        "config": "^3.3.1",
        "cors": "^2.8.5",
        "express": "^4.17.1",
        "express-fileupload": "^1.1.7-alpha.3",
        "express-validator": "^6.5.0",
        "jsonwebtoken": "^8.5.1",
        "nodemon": "^2.0.4",
        "pg": "^8.2.1",
        "pg-hstore": "^2.3.3",
        "sequelize": "^5.21.11",
        "sequelize-cli": "^5.5.1"
      },
      "engines": {
        "node": "12.0.0"
      }
    }
    
    server.js
    
    const express = require('express');
    const bodyParser = require('body-parser');
    const app = express();
    const PORT = process.env.PORT || 5000;
    
    const upload = require('express-fileupload');
    app.use(upload({useTempFiles: true}));
    
    const cors = require('cors');
    const path = require('path');
    const models = require('./models');
    
    // variable to enable global error logging
    const enableGlobalErrorLogging =
      process.env.ENABLE_GLOBAL_ERROR_LOGGING === 'true';
    
    // Enable All CORS Requests
    app.use(cors());
    
    //Init Middleware
    app.use(bodyParser.json());
    app.use(
      bodyParser.urlencoded({
        extended: true,
      })
    );
    
    //app.use(express.static(path.join(__dirname, 'client/build')));
    
    console.log(process.env.NODE_ENV);
    //if running in production mode then it serves static files from build in client
    if (process.env.NODE_ENV === 'production') {
      //points to index.js in client
      app.use(express.static(path.join(__dirname, 'client/build')));
    }
    
    //Routes
    app.use('/users', require('./routes/users'));
    app.use('/auth', require('./routes/auth'));
    app.use('/posts', require('./routes/posts'));
    app.use('/api/profile', require('./routes/profile'));
    app.use('/adventure', require('./routes/adventure'));
    app.use('/review', require('./routes/review'));
    app.use('/favorites', require('./routes/favorites'));
    app.use('/upload', require('./routes/uploadImage'));
    
    //catch all method redirects to build folder
    app.get('*', (req, res) => {
      res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
    });
    
    // send 404 if no other route matched
    app.use((req, res) => {
      res.status(404).json({
        message: 'Route Not Found',
      });
    });
    
    // setup a global error handler
    app.use((err, req, res, next) => {
      console.log('I am catching the error');
      if (enableGlobalErrorLogging) {
        console.error(`Global error handler: ${JSON.stringify(err.stack)}`);
      }
      if (err.name === 'SequelizeUniqueConstraintError') {
        return res.status(400).json({
          errors: ['Email for user already exists'],
        });
      }
      // if (err.name === 'SequelizeDatabaseError') {
      //   return res.status(404).json({errors: 'Oh no! Page not found.'});
      // }
      res.status(err.status || 500).json({
        message: err.message,
        name: err.name,
        error: {},
      });
    });
    
    //Sets Port and Listens
    return models.sequelize.sync().then((result) => {
      app.listen(process.env.PORT || 5000, () => {
        console.log(`App running on port ${process.env.PORT || 5000}.`);
      });
    });
    
    配置文件
    if (process.env.NODE_ENV !== 'production') require('dotenv').config();
    //PG_HOST = 127.0.0.1
    
    console.log(process.env.DATABASE_URL);
    module.exports = {
      development: {
        username: process.env.PG_USER,
        password: process.env.PG_PASSWORD,
        database: process.env.PG_DATABASE,
        host: process.env.PG_HOST,
        dialect: 'postgres',
        port: process.env.PG_PORT,
        operatorsAliases: 0,
      },
      test: {
        username: process.env.PG_USER,
        password: process.env.PG_PASSWORD,
        database: process.env.PG_DATABASE,
        host: process.env.PG_HOST,
        dialect: 'postgres',
        port: process.env.PG_PORT,
        operatorsAliases: 0,
      },
      production: {
        use_env_variable: process.env.DATABASE_URL,
        dialect: 'postgres',
        dialectOptions: {
          ssl: true,
        },
      },
    };
    
    Procfile
    
    web: node server.js
    
    编辑
    我做了一个错误报告,我实际上认为我可能已经修复了 node_modules 包中抛出错误的问题。现在我必须弄清楚如何在 Heroku 中进行更改,因为我们不提交 node_modules 来查看它是否有效。我现在可以在生产模式下在本地运行它,而不会重现错误。
    如果有人感兴趣,请报告错误
    https://github.com/sequelize/sequelize/issues/12528

    最佳答案

    在你的配置文件中试试这个

    production: {
        use_env_variable: "DATABASE_URL",
        dialect: 'postgres',
        dialectOptions: {
          ssl: true,
        },
      },
    
    由于您使用的是 use_env_variable,因此您应该能够将变量的名称作为值。

    关于node.js - Sequelize-CLI、Postgres、Heroku 生产 TypeError [ERR_INVALID_ARG_TYPE] : The "url" argument must be of type string. 接收类型未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62975561/

    相关文章:

    ruby-on-rails-3 - Rails 3:Heroku 中未初始化的常量 IRB::ReadlineInputMethod::Readline (NameError)

    java - Heroku 继续使用 Postgres 而不是 MySQL

    javascript - 使用旧版本的 Node 创建 React App

    javascript - 初学者在这里。我需要帮助更好地理解这个回调函数

    postgresql - 将来自不同表的查询结果添加到 PostgreSQL 中的新表

    sql - 如何使用for循环在postgresql中插入数据?

    ruby-on-rails - Rails heroku 应用程序上的 Robots.txt 文件未更新

    node.js - 为什么express.js应用程序几乎总是位于nginx或其他Web服务器后面?

    node.js - Mongoose 在子文档属性上强制执行唯一属性

    SQL:选择不同的左边