Node.js проект развернут на Heroku. Не удается получить доступ к конечным точкам API и подключиться к MongoDB Atlas. Возвращается статус 404

#node.js #mongodb #heroku

#node.js #mongodb #heroku

Вопрос:

Я пытался найти вопрос, похожий на мой, и я просматриваю Google, журналы и пытаюсь исправить эту проблему целый день без какого-либо успеха. Я надеюсь, что вы, ребята, сможете мне помочь.

У меня есть Node.js API с Express развернут на Heroku, и я пытаюсь подключить его к MongoDB Atlas. В начале в журналах была проблема с производственными переменными, с которой я разобрался. Но все же, когда я пытаюсь получить доступ к любой конечной точке API, я получаю журналы:

 2021-01-23T17:49:34.346738 00:00 heroku[web.1]: Starting process with command `npm start`
2021-01-23T17:49:36.180974 00:00 app[web.1]:
2021-01-23T17:49:36.180991 00:00 app[web.1]: > eastern-beauty-backend@1.0.0 start /app
2021-01-23T17:49:36.180991 00:00 app[web.1]: > node index.js
2021-01-23T17:49:36.180991 00:00 app[web.1]:
2021-01-23T17:49:36.921969 00:00 app[web.1]: [winston] Attempt to write logs with no transports {"message":"Listening on port 31690...","level":"info"}
2021-01-23T17:49:36.926481 00:00 app[web.1]: (node:21) UnhandledPromiseRejectionWarning: MongoParseError: Invalid connection string
2021-01-23T17:49:36.926482 00:00 app[web.1]: at parseConnectionString (/app/node_modules/mongodb/lib/core/uri_parser.js:565:21)
2021-01-23T17:49:36.926483 00:00 app[web.1]: at connect (/app/node_modules/mongodb/lib/operations/connect.js:282:3)
2021-01-23T17:49:36.926484 00:00 app[web.1]: at /app/node_modules/mongodb/lib/mongo_client.js:224:5
2021-01-23T17:49:36.926484 00:00 app[web.1]: at maybePromise (/app/node_modules/mongodb/lib/utils.js:665:3)
2021-01-23T17:49:36.926484 00:00 app[web.1]: at MongoClient.connect (/app/node_modules/mongodb/lib/mongo_client.js:220:10)
2021-01-23T17:49:36.926485 00:00 app[web.1]: at /app/node_modules/mongoose/lib/connection.js:833:12
2021-01-23T17:49:36.926486 00:00 app[web.1]: at new Promise (<anonymous>)
2021-01-23T17:49:36.926486 00:00 app[web.1]: at NativeConnection.Connection.openUri (/app/node_modules/mongoose/lib/connection.js:830:19)
2021-01-23T17:49:36.926486 00:00 app[web.1]: at /app/node_modules/mongoose/lib/index.js:345:10
2021-01-23T17:49:36.926486 00:00 app[web.1]: at /app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:31:5
2021-01-23T17:49:36.926487 00:00 app[web.1]: at new Promise (<anonymous>)
2021-01-23T17:49:36.926487 00:00 app[web.1]: at promiseOrCallback (/app/node_modules/mongoose/lib/helpers/promiseOrCallback.js:30:10)
2021-01-23T17:49:36.926487 00:00 app[web.1]: at Mongoose._promiseOrCallback (/app/node_modules/mongoose/lib/index.js:1135:10)
2021-01-23T17:49:36.926488 00:00 app[web.1]: at Mongoose.connect (/app/node_modules/mongoose/lib/index.js:344:20)
2021-01-23T17:49:36.926488 00:00 app[web.1]: at module.exports (/app/startup/db.js:7:12)
2021-01-23T17:49:36.926488 00:00 app[web.1]: at Object.<anonymous> (/app/index.js:9:24)
2021-01-23T17:49:36.926591 00:00 app[web.1]: (node:21) 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)
2021-01-23T17:49:36.926651 00:00 app[web.1]: (node:21) [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.
2021-01-23T17:49:37.268649 00:00 heroku[web.1]: State changed from starting to up
2021-01-23T17:49:38.509600 00:00 heroku[router]: at=info method=GET path="/" host=eastern-beauty-api.herokuapp.com request_id=d4f01cf5-9a03-43c0-b90c-502e1526d2b6 fwd="148.252.132.237" dyno=web.1 connect=0ms service=10ms status=404 bytes=415 protocol=https
2021-01-23T17:49:43.261992 00:00 heroku[router]: at=info method=GET path="/users" host=eastern-beauty-api.herokuapp.com request_id=7b2758e9-d3d9-4c5d-b693-af513424e7bd fwd="148.252.132.237" dyno=web.1 connect=0ms service=2ms status=404 bytes=420 protocol=https
2021-01-23T17:50:06.222493 00:00 heroku[router]: at=info method=GET path="/users" host=eastern-beauty-api.herokuapp.com request_id=dc17bb7f-8cb9-4e2b-ac5a-054edb95fb27 fwd="148.252.132.237" dyno=web.1 connect=0ms service=2ms status=404 bytes=420 protocol=https  
 

и возвращаемый статус 404 «Не найден».

Он отлично работает в режиме разработки. Я устанавливаю пользовательскую переменную среды для подключения к MongoDB Atlas и заменяю имя пользователя, пароль и dbname там, где требуется.

 mongodb srv://<username>:<password>@eb.bvm0d.mongodb.net/<dbname>?retryWrites=trueamp;w=majority
 

Я попытался подключиться к оболочке, и проблем не было. Я думаю, что в моем коде что-то не так, но я ничего не могу обнаружить.

Вот некоторые из файлов, которые у меня есть:

index.js

 const winston = require("winston");
const express = require("express");
const config = require("config");
const app = express();


require("./startup/cors")(app);
require("./startup/routes")(app);
require("./startup/db")();
require("./startup/config")();
require("./startup/validation")();

const port = process.env.PORT || config.get("port");
const server = app.listen(port, () =>
  winston.info(`Listening on port ${port}...`)
);

module.exports = server;
 

startup/routes.js

 const express = require('express');
const error = require('../middleware/error');
const auth = require('../routes/auth');
const users = require('../routes/users');
const customers = require('../routes/customers');
const herbs = require('../routes/herbs');
const herbsBG = require('../routes/herbsBG');
const oils = require('../routes/oils');
const oilsBG = require('../routes/oilsBG');

module.exports = function(app) {
  app.use(express.json());
  app.use('/api/auth', auth);
  app.use('/api/users', users);
  app.use('/api/customers', customers);
  app.use('/api/herbs', herbs);
  app.use('/api/herbsBG', herbsBG);
  app.use('/api/oils', oils);
  app.use('/api/oilsBG', oilsBG);
  app.use(error);
}
 

startup/db.js

 const winston = require('winston');
const mongoose = require('mongoose');
const config = require('config');

module.exports = function() {
  const db = config.get('db');
  mongoose.connect(db, { useNewUrlParser: true })
    .then(() => winston.info(`Connected to ${db}...`));
}
 

config/default.json

 {
  "jwtPrivateKey": "unsecureKey",
  "db": "mongodb://localhost/ebeauty",
  "port": "3900",
  "requiresAuth": false
}
 

config/production.json

 {
  "jwtPrivateKey": "EB_jwtPrivateKey",
  "db": "eb_db"
}
 

Внутри production.json я объявляю пользовательские переменные среды. Переменные находятся в Heruko, и идея состоит в том, чтобы быть скрытыми в целях безопасности. Затем в разделе «eb_db» на Heroku я размещаю URL-адрес для соединения с MongoDB.

Спасибо за вашу помощь!

Ответ №1:

Соответствующая ошибка

Предупреждение о необработанном promiserejectionwarning: MongoParseError: недопустимая строка подключения

Местоположение было

в parseConnectionString (/app/node_modules/mongodb/lib/core/uri_parser.js:565:21)

Если вы используете последнюю версию драйвера, этот код (из github):

       if (parsedHost.path === '/:') {
        hostParsingError = new MongoParseError('Double colon in host identifier');
        return null;
      }
 

Это, по-видимому, подразумевает неэкранированный специальный символ или отсутствующую переменную среды.

Комментарии:

1. Итак, что я должен делать? Единственный успех, который у меня есть на данный момент, — это если я не использую переменные среды и помещаю строку подключения mongdb atlas прямо в производство. файл json в разделе «db». Я знаю, что это плохая практика, но я пытаюсь найти проблему. Когда я делаю это так, я не получаю столько ошибок. Только этот «(узел: 21) Предупреждение об устаревании: collection.ensureIndex устарел. Вместо этого используйте createIndexes «. И в моем кластере я вижу соединения, но по-прежнему не удается получить данные в конечных точках API. Я не знаю, что еще делать….

2. Вы можете распечатать строку подключения в журнале прямо перед вызовом connect, чтобы вы могли точно видеть, что он использует.