I built a NodeJS Express & MongoDB web application that is working well locally.
I tried to deploy it.
Eventhough, the application is partially working in production mode, some of its pages are not displaying.
For example, I'm not able to access the blog page and the following message error displays instead of the content of the page:
Incomplete response received from application
Therefore, I logged the blog page and got the error message below:
App 814821 output: node:internal/process/promises:279 App 814821
output: triggerUncaughtException(err, true /* fromPromise /); App
814821 output: ^ App 814821 output: [UnhandledPromiseRejection: 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(). The promise rejected with the reason "#".] {
App 814821 output: code: 'ERR_UNHANDLED_REJECTION' App 814821 output:
} [ W 2022-11-19 10:30:01.7998 813657/Tg
age/Cor/Con/InternalUtils.cpp:96 ]: [Client 5-1] Sending 502 response:
application did not send a complete response [ N 2022-11-19
10:30:01.8095 813657/Ti age/Cor/CoreMain.cpp:1147 ]: Checking whether
to disconnect long-running connections for process 814821, application
/home/raso1970/node-com4muz (development) App 815207 output:
node:internal/process/promises:279 App 815207 output:
triggerUncaughtException(err, true / fromPromise */); App 815207
output: ^ App 815207 output: [UnhandledPromiseRejection: 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(). The promise rejected with the reason "#".] { App
815207 output: code: 'ERR_UNHANDLED_REJECTION' App 815207 output: } [
W 2022-11-19 10:30:03.7100 813657/Ti age/Cor/Con/InternalUtils.cpp:96
]: [Client 6-1] Sending 502 response: application did not send a
complete response [ W 2022-11-19 10:30:05.0596 813657/T3
age/Cor/App/Poo/AnalyticsCollection.cpp:102 ]: Process (pid=815207,
group=/home/raso1970/node-com4muz (development)) no longer exists!
Detaching it from the pool. [ N 2022-11-19 10:30:05.0597 813657/T3
age/Cor/CoreMain.cpp:1147 ]: Checking whether to disconnect
long-running connections for process 815207, application
/home/raso1970/node-com4muz (development)
I guess the issue comes from MongoDB?
Maybe I did not set up the connection correctly?
Here is my code related to the MongoDB database connection:
data\database.js:
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
let database;
let mongodbUrl = 'mongodb://127.0.0.1:27017';
let MONGODB_URL = 'mongodb+srv://<username>:<password>#cluster0.42o6qd6.mongodb.net/?retryWrites=true&w=majority'
if (process.env.MONGODB_URL) {
mongodbUrl = process.env.MONGODB_URL;
}
async function connect() {
const client = await MongoClient.connect(mongodbUrl);
database = client.db('com4muz-blog');
}
function getDb() {
if (!database) {
throw { message: 'Database connection not established!' };
}
return database;
}
module.exports = {
connectToDatabase: connect,
getDb: getDb
};
Indeed, I did write my username and password instead of <username> and <password> to the MONGODB_URL value.
app.js:
const path = require('path');
const express = require('express');
const session = require('express-session');
const sessionConfig = require('./config/session');
const db = require('./data/database');
const adminRoutes = require('./routes/admin/blog');
const authRoutes = require('./routes/admin/auth');
const defaultRoutes = require('./routes/home/default');
const postsRoutes = require('./routes/home/posts');
const quotationsRoutes = require('./routes/home/quotations');
const contactsRoutes = require('./routes/home/contacts');
const authMiddleware = require('./middlewares/auth-middleware');
const mongoDbSessionStore = sessionConfig.createSessionStore(session);
let port = 3000;
if (process.env.MONGODB_URL) {
port = process.env.MONGODB_URL;
}
const app = express();
app.set('views', [
path.join(__dirname, 'views/home'),
path.join(__dirname, 'views/admin')
]);
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use('/public/admin/images', express.static('public/admin/images'));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(session(sessionConfig.createSessionConfig(mongoDbSessionStore)));
app.use(authMiddleware);
app.use('/', adminRoutes);
app.use('/', authRoutes);
app.use('/', defaultRoutes);
app.use('/', postsRoutes);
app.use('/', quotationsRoutes);
app.use('/', contactsRoutes);
app.use(function (req, res) {
res.status(404).render('404');
});
app.use(function (error, req, res, next) {
console.error(error);
res.status(500).render('500');
});
if (typeof(PhusionPassenger) !== 'undefined') {
PhusionPassenger.configure({ autoInstall: false });
}
if (typeof(PhusionPassenger) !== 'undefined') {
app.listen('passenger');
} else {
app.listen(3000);
}
I'm using o2switch as a hosting server. They use the Setup Node.js App tool, which deploy the website through Phushion Passenger.
Related
I’ve been having an issue with deploying my nodejs App on AWS ECS Fargate. Running the app locally on my device with nodemon or building the app and running the build file is successful and I can ping my routes using postman. The issue happens when I deploy this same exact code on AWS; using postman, to do a POST request, I get a 404 error. Please note, I'm running a Node:14 container.
For reference, my nodejs code is structured in a way where there’s a main route.js file containing all routes, then there are specific route files, for example listingRoute.js, contains all the sub-routes then there are controllers (.js files) containing all the logic where I export the function and tie it with the route in the listingRoute.js example.
Here's what my main Route.js file looks like:
const express = require('express');
const error = require('../Middleware/error');
const listingRoute = require('../Routes/listingRoute');
module.exports = function (app) {
//Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: false , limit : '20mb' }));
app.use('/listing', listingRoute);
//The final middleware to be called in case of an unhandled error.
app.use(error);
process.on('uncaughtException', function(err) {
// Handle the error safely
console.log(err)
})
};
My listingRoute file
const express = require("express");
const route = express.Router();
const listingController = require("../Controllers/listingController");
require('dotenv').config();
route.post("/create", listingController.createListing)
route.post("/update", listingController.updateListing)
route.post("/read", listingController.getListing)
route.post("/delete", listingController.deleteListing)
...
...
...
...
...
route.post("/getMostPopular" , listingController.getMostPopular)
route.post("/getByCategory" , listingController.getByCategory)
route.post("/getAllTOS" , TOSController.getTOSByListing)
route.post("/getTOS" , TOSController.getTOSByID)
route.post("/updateTOS" , TOSController.updateTOS)
route.post("/deleteTOS" , TOSController.deleteTOS)
route.post("/createTOS" , TOSController.createTOS)
route.post("/getListingsByIDs" , listingController.getListingsByIDs)
route.post("/cacheImagesNewCDN" , listingController.cacheImagesNewCDN)
module.exports = route;
My listingController file
const listingModel = require('../Models/listingModel');
const moment = require('moment')
const axios = require('axios');
var fs = require('fs');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
var fs = require('fs');
//tested
const createListing =async (req, res) => {
try {
//some logic here
}
catch (err) {
console.log(err)
return res.status(500).json({ error: err.message });
}
}
const updateListing = async (req, res) => {
try {
//some logic here
}
catch (err) {
return res.status(500).json({ error: err.message });
}
}
module.exports = {
getListing,
updateListing,
deleteListing,
createListing,
listingwithViews,
advertisedListings,
filterListings,
pressedOnBookNow,
cacheImages,
recommendListings,
getCacheMetaData,
addIndoorAmenity,
missingFromFilter,
adjustCreativeStudios,
listingsToCSV,
getAllListing,
getDiscountedListings,
addRevenueToListings,
getMostPopular,
getByCategory,
getListingsByIDs,
cacheImagesNewCDN,
getOwnersPhones
}
All the routes starting from getMostPopular till the end of the list give an error 404 not found although I have done the same procedure to all of them. Any ideas why this is happening? If you feel this isn't enough information to help diagnose, let me know and i'd be happy to provide more details. You're help would be beyond appreciated, thanks!
I am creating my first web application using the MEVN stack (MongoDb, Express, VueJS, Node). As far as I can tell from research, functions in my node server.js file are all async by default, but every time I make a request (POST/GET whatever) to the API, it halts the backend until that function has resolved. I need users who use the website to be able to send GET requests to the site while another user is uploading info to the DB for instance with a POST request in another function. Currently it just halts all calls until the first one resolves. I am testing by going to /test on my server with a 5 second wait, while simultaneously making a call to /api in Postman. The Postman request just hangs until the /test function resolves. I'm sure this is a novice issue, but why is this not functioning asynchronously? I have pasted the head from my server.js below
// Importing required modules
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const morgan = require('morgan');
const multer = require('multer');
const hashlips = require('./src/main.js')
const fs = require('fs-extra');
// parse env variables
require('dotenv').config();
require("./helpers/db/mongodb.js")();
// Configuring port
const port = process.env.PORT || 9000;
//configure express
const app = express();
// Configure middlewares
app.use(cors());
app.use(express.json({ limit: '10mb' }));
app.use(morgan('dev'));
app.use(bodyParser.json({ limit: '10mb' }));
app.use(express.urlencoded({extended: true}, { limit: '10mb' }));
app.set('view engine', 'html');
// Static folder
app.use(express.static(__dirname + '/views/'));
// Defining route middleware
app.use('/api', require('./routes/api'));
//routes
app.get('/test', (req, res) => {
await new Promise(r => setTimeout(r, 5000));
res.send("<h3>Express Server")
})
Here' is my api.js
const express = require('express');
const {
//init CRUD
createData,
readData,
updateData,
deleteData,
deleteAllData,
//init register login
registerNewUser,
loginUser,
getUserDetails,
//init collection saving
createCollection,
readCollectionData,
deleteAllCollections,
deleteCollection,
updateCollection,
} = require('../controllers/user_controller');
const auth = require('../config/auth')
const router = express.Router();
router
.put("/collection", createCollection)
.put("/collectionu", updateCollection)
.post("/", createData)
.post("/register", registerNewUser)
.post("/login", loginUser)
.get("/collection", readCollectionData)
.get("/me", auth, getUserDetails)
.get('/', readData)
.put('/:id', updateData)
.delete('/deletecollections', deleteAllCollections)
.delete('/deleteall', deleteAllData)
.delete('/deletecollection/:id', auth, deleteCollection)
.delete('/:id', deleteData);
module.exports = router;
Any help would be greatly appreciated! Idk if it's helpful but here's my --trace-sync-io stack trace:
(node:62551) WARNING: Detected use of sync API
at pbkdf2Sync (node:internal/crypto/pbkdf2:80:37)
at HI (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/auth/scram.js:245:31)
at continueScramConversation (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/auth/scram.js:138:28)
at /home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/auth/scram.js:90:9
at onMessage (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/connection.js:222:9)
at /home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/connection.js:63:60
at emit (node:events:394:28)
at processIncomingData (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/message_stream.js:132:20)
at _write (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/message_stream.js:33:9)
at writeOrBuffer (node:internal/streams/writable:389:12)
Connected to MongoDB
(node:62551) WARNING: Detected use of sync API
at randomFillSync (node:internal/crypto/random:137:19)
at randomBytes (node:internal/crypto/random:99:5)
at uuidV4 (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/utils.js:439:27)
at ServerSession (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/sessions.js:541:62)
at acquire (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/sessions.js:619:16)
at get serverSession (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/sessions.js:94:46)
at applySession (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/sessions.js:670:35)
at command (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/connection.js:278:53)
at /home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/sdam/server.js:210:18
at /home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongodb/lib/cmap/connection_pool.js:271:13
(node:62551) WARNING: Detected use of sync API
at randomFillSync (node:internal/crypto/random:137:19)
at randomBytes (node:internal/crypto/random:99:5)
at ObjectId.generate (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/bson/lib/objectid.js:145:54)
at ObjectId (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/bson/lib/objectid.js:47:34)
at NativeCollection.<computed> (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:84:18)
at create (/home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongoose/lib/model.js:1803:22)
at /home/zach/Documents/WebProjects/mevn/ezmode/server/node_modules/mongoose/lib/model.js:1764:7
at processTicksAndRejections (node:internal/process/task_queues:78:11)
I'm having trouble with the error message in the title when trying to retrieve all users in my express .get('/users') method. I am using Node.js, Express, and node-postgres. I have my
getUsers(); function defined in my queries.js file, and I call the function in my app.get() function in my index.js file.
queries.js
const client = require('./object models/db_client_pool')
const Pool = require('pg').Pool
const pool = new Pool(client.client)
async function getUsers(request, response) {
await pool.connect()
pool.query('select * from discord_users', (error, results) => {
if (error) {
throw error
}
response.sendStatus(200).json(results.rows)
pool.release();
})
}
module.exports = {
getUsers
}
index.js
const express = require('express');
require('dotenv').config();
//const bodyParser = require('body-parser'); deprecated
const app = express();
const port = 3000;
const db = require('./queries');
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.get('/', (request, response) => {
response.json({ info: 'Node.js, Express, and Postgres API' })
})
app.get('/users', (req, res) => {
db.getUsers(req, res)
})
app.listen(port, () => {
console.log(`App is listening on port ${port}`);
});
As I said, I keep getting the "cannot set headers after they are sent to the client" error and I'm at a loss of what to do. Thanks in advance for your help!
Change from this:
response.sendStatus(200).json(results.rows)
to this:
response.status(200).json(results.rows);
or even just to this:
response.json(result.rows); // 200 is the default status already
The last one is fine because 200 is already the default status so you don't need to set that yourself.
The problem is that response.sendStatus(200) sends a complete response with an empty body and then you try to call response.json(result.rows) which tries to send ANOTHER response to the same request. Trying to send that second response to the same request is what triggers the error message you are getting.
response.status(200) just sets the status to 200 as a property on the waiting response object and waits for some other method to actually send the response itself which you can then do with .json(...).
So my guess is, you're running express 4.x and that doesn't support response.sendStatus(200) anymore. You have to use response.status(200) instead.
Now, another issue I see in your code is, I don't recognize pool.release() method from pg library. You can release a client back to a pool but you can't release a pool of clients. Maybe you meant pool.end()?
# Rendering React on Node.js server? #
================================================================================================
## Intro ##
Hello, I am trying to build a node.js server, and render React with it. I have been trying to follow some online tutorials, in the process getting a little lost. I understand GET/POST routes. I know my server.js need to render my index.js'. My React code runs fine with the React environment with npm start` in the shell/terminal.
## The Error ##
My Error happens when I attempt to run my server via "nodemon server.js" in the terminal.
[nodemon] starting `node server.js`
(node:10748) ExperimentalWarning: The ESM module loader is experimental.
file:///C:/Users/The%20core%20unit/Desktop/Code%20file%20storage/React/react-app/server.js:42
const app = ReactDOMServer.renderToString(<Index />);
^
SyntaxError: Unexpected token '<'
at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)
at async link (internal/modules/esm/module_job.js:41:21)
[nodemon] app crashed - waiting for file changes before starting...
I know this Error is telling me that my server.js can not read the React code.
### server.js ###
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const https = require("https");
const { Server } = require("http");
const app = express();
import Index from "./src/index.js"
import ReactDOMServer from 'react-dom/server'
import path from 'path';
import fs from 'fs';
// Error List //
/*Server is starting, however not rendering any data. */
//Mongoose connection to MongoDB//
mongoose.connect("mongodb://localhost:27017/watchesDB",{ useUnifiedTopology: true, useNewUrlParser: true});
//Mongoose Schema//
const watchesSchema = {
Company: String,
Model: String,
Year: Number
};
const Watch = mongoose.model("Watch", watchesSchema);
//Boiler Plate Code for Server//
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
// API call Routes //
//Home APi call
app.get('/', (req, res) => {
const app = ReactDOMServer.renderToString(<Index />);
const indexFile = path.resolve("./public/index.htlm");
fs.readFile(indexFile, 'utf8', (err, data) => {
if (err) {
console.error('Something went wrong:', err);
return res.status(500).send('Oops, better luck next time!');
}
return res.send(
data.replace(`<div id="root"></div>`, `<div id="root">${app}</div>`)
);
});
});
app.use(express.static('./build'));
//Watches API call
app.get("/watches", function(req, res){
Watch.find(function(err, foundWatches) {
console.log(foundWatches)
});
});
// Server listing //
app.listen(3000, function(){
console.log("Server accessfully booted...")
});
### index.js ###
import ReactDOM from 'react-dom';
import Heading from "./Heading";
import Watch from "./Watch";
function Index() {
ReactDOM.render(<div>
<Heading />
<Watch /></div>,
document.getElementById('root')
);
};
export default Index
[Pic of index.js][1]
[Pic of server.js][2]
I'm getting a problem opening up my app. I already built the app using create-react-app (nodejs and express on the backend) and it's "colorsofemre.com". When I'm trying to make changes in the app though, all I get is a CANNOT GET / error on the browser.
This is my server.js
const express = require('express')
const app = express()
port = process.env.PORT || 3000 ;
var bodyParser = require('body-parser')
var path = require("path")
app.use(bodyParser.json());
var cors = require('cors');
app.use(cors());
app.use('public', express.static(path.join(__dirname, 'src')));
app.use('public', express.static(path.join(__dirname, 'public')));
app.get('/color', async (req, res) => {
MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => {
if (err) return console.log(err)
// Storing a reference to the database so you can use it later
db = client.db('ColorPicker')
db.collection('Colors').find({}).toArray((err,result)=>{
if(err) throw err;
console.log(result);
res.status(200).json(result)
console.log(result);
})
});
});
app.listen(port,()=>{console.log("Listening on port"+port)});
This is my client side fetch function the get /color.
async updateArray(){
this.colors=[];
const result = await fetch(`http://localhost:3000/color`,{mode: 'cors'});
const data = await result.json();
this.arrayModified(data);
this.setState({render:true});
}
When I enable the client side I get this error
Unhandled Rejection (SyntaxError): The string did not match the expected pattern.
21 |
22 | this.colors=[];
23 | const result = await fetch(`http://localhost:3000/color`,{mode: 'cors'});
> 24 | const data = await result.json();
| ^ 25 | this.arrayModified(data);
26 | this.setState({render:true});
27 | }
And if I comment the client side fetch code, I only get Cannot /GET on my browser. Database works fine and when I go to localhost:3000/color, json data is loaded perfectly.
My file structure is
-public
-index.html
-src
-index.js
-app.js
-and other js components
-server.js
I've been trying to figure out what's wrong for 2 days. Thank youu!
Try adding a catch-all route like this to your server.js, to redirect your GET requests to index.html first:
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
})
Source: Fixing the "cannot GET /URL" error on refresh with React Router and Reach Router (or how client side routers work)