Deploying Express app to Vercel gives errors - javascript

Running the server locally produces no problems, however when I deploy to Vercel I get the following error:
TypeError: Cannot read properties of undefined (reading 'startsWith') at connectionStringHasValidScheme (/var/task/server/node_modules/mongodb-connection-string-url/lib/index.js:9:30) at new ConnectionString (/var/task/server/node_modules/mongodb-connection-string-url/lib/index.js:85:34) at parseOptions (/var/task/server/node_modules/mongodb/lib/connection_string.js:201:17) at new MongoClient (/var/task/server/node_modules/mongodb/lib/mongo_client.js:46:63) at Object.<anonymous> (/var/task/server/db/conn.js:3:16) at Module._compile (node:internal/modules/cjs/loader:1159:14) at Module._extensions..js (node:internal/modules/cjs/loader:1213:10) at Module.load (node:internal/modules/cjs/loader:1037:32) at Module._load (node:internal/modules/cjs/loader:878:12) at Module.require (node:internal/modules/cjs/loader:1061:19)
I'm really not sure what the problem is - I've done a bit of googling but it hasn't produced many results for this issue (at least not that I found).
server.js
const express = require("express");
const app = express();
const cors = require("cors");
const bp = require('body-parser');
require("dotenv").config({ path: "./db/config.env" });
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
app.use(require("./routes/auth"));
app.use(require("./routes/user"));
const dbo = require("./db/conn");
app.listen(port, () => {
dbo.connectToServer(function (err) {
if (err) console.error(err);
});
console.log(`Server is running on port: ${port}`);
});
conn.js
const { MongoClient } = require("mongodb");
const Db = process.env.ATLAS_URI;
const client = new MongoClient(Db, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
var _db;
module.exports = {
connectToServer: function (callback) {
client.connect(function (err, db) {
// Verify we got a good "db" object
if (db)
{
_db = db.db("preview");
console.log("Successfully connected to MongoDB.");
}
return callback(err);
});
},
getDb: function () {
return _db;
},
};
I tried cutting the code down to a minimal just to figure out what component is causing the bug, unfortunately with no result.

When you deploy your app to Vercel, you also need declare your environment variables in your project settings page.
Go to the Environment Variables page of your Project Settings and define ATLAS_URI value. Note that you need to deploy your project again before new environment variables becomes available.

Related

TypeError('app.use() requires a middleware function')

enter image description here
here's the app.js(--please find attached image):
//here's the app.js
const express = require("express");
const app = express();
app.use(express.json());
const morgan = require("morgan");
const mongoose = require("mongoose");
const cors = require("cors");
require("dotenv/config");
const authJwt = require("./helpers/jwt");
const errorHandler = require("./helpers/error-handler");
app.use(cors());
app.options('*', cors());
//middleware
app.use(morgan("tiny"));
app.use(authJwt());
app.use(errorHandler()); //-> **this isn't correct?**
//Importing routing of products
const categoriesRoutes = require("./routes/categories");
const productsRoutes = require("./routes/products");
const usersRoutes = require("./routes/users");
const ordersRoutes = require("./routes/orders");
const req = require("express/lib/request");
const res = require("express/lib/response");
const api = process.env.API_URL;
//routers
app.use(`${api}/products`, productsRoutes);
app.use(`${api}/categories`, categoriesRoutes);
app.use(`${api}/orders`, ordersRoutes);
app.use(`${api}/users`, usersRoutes);
//Database
mongoose
.connect(process.env.CONNECTION_STRING, {
useNewurlParser: true,
useUnifiedTopology: true,
dbName: "eshop-database",
})
.then(() => {
console.log("database connection is ready");
})
.catch((err) => {
console.log(err);
});
//Server
app.listen(3000, () => {
console.log("Server is Running http://http://localhost:3000");
});
//error image
//here's the error handler code
function errorHandler(err, req, res, next){
if (err) {
res.status(500).json({message: err})
}
}
module.exports = errorHandler;
> Blockquote (--please find attached image)
here's the error
C:\Users\steve\Backend\node_modules\express\lib\application.js:210
throw new TypeError('app.use() requires a middleware function')
^
TypeError: app.use() requires a middleware function
at Function.use (C:\Users\steve\Backend\node_modules\express\lib\application.js:210:11)
at Object.<anonymous> (C:\Users\steve\Backend\app.js:17:5)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
Your error handler function is correct, but the problem is that you're calling the function instead of passing it directly to your express app.
Remove the parenthesis after the errorHandler and it should work.
app.use(errorHandler); // Don't call errorHandler, express will call it
Think of it like this.
if I just call errorHandler() in any context it won't return anything.
That means that errorHandler() evaluates to undefined.
Now in your code, when you do app.use(errorHandler()) instead of evaluating to the following:
app.use(function(err, req, res, next){
if (err) {
res.status(500).json({message: err})
}
});
Your code is actually evaluating to
app.use(undefined);
and so express is throwing an error because undefined is not a function.

Node JS app shuts down after ten seconds in Production env but runs fine on local env

I have a Node JS app which serves as a backend for a React web app. The application when started serves the React app and handles all the API calls. I connect to a MySQL database for data fetch. The app runs normally on local environment but crashes when deployed on an Ubuntu server(on AWS). On server, the app starts normally but after few seconds it crashes.
This is the error it throws when started
Error connecting: Error: connect ETIMEDOUT
at PoolConnection.Connection._handleConnectTimeout (/home/ubuntu/localSystem/node_modules/mysql/lib/Connection.js:412:13)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:106:13)
at Socket.emit (events.js:208:7)
at Socket._onTimeout (net.js:422:8)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5)
--------------------
at Protocol._enqueue (/home/ubuntu/localSystem/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (/home/ubuntu/localSystem/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at PoolConnection.connect (/home/ubuntu/localSystem/node_modules/mysql/lib/Connection.js:119:18)
at Pool.getConnection (/home/ubuntu/localSystem/node_modules/mysql/lib/Pool.js:48:16)
at Object.<anonymous> (/home/ubuntu/localSystem/model/db.js:29:12)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
DB connection file (db.js):
var connection = mysql.createPool({
connectionLimit: 100,
host : 'xxxx',
port : xxxx,
user : 'username',
password : 'password',
database : 'myDB'
});
connection.getConnection(function(err) {
if (err) {
console.log('Error connecting: ' + err.stack)
return;
}
console.log('Connected as id ' + connection.threadId)
});
module.exports = connection;
Server.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
app = express();
var appRoutes = require('./routes/appRoutes');
app.use(express.static(path.join(__dirname, './client/build')));
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', appRoutes);
module.exports = app;
index.js
var app = require('./server');
//const { connection } = require('./database');
var port = 5001;
app.set('port', port);
app.listen(app.get('port'), () => {
console.log(`server on port ${app.get('port')}`);
});
AppModel.js
var sql = require('./db.js');
//Task object constructor
var Task = function(task){
this.task = task.task;
this.status = task.status;
this.created_at = new Date();
};
Task.getAllCustomerStatusRecords = function getAllCustomerStatusRecords(result) {
sql.query("Select a, b, c, call_provider_id from myTable order by id desc limit 20", function (err, res) {
if(err) {
console.log("error: ", err);
result(null, err);
}
else {
console.log('Customer status records : ', res);
result(null, res);
}
});
sql.releaseConnection()
};
I have a similar set up for another Node app but without mysql and it runs without issues.I'm not sure why it crashes in this case.
EDIT:
The API request does make a DB call. However that is only when the user explicitly selects some options and then makes a fetch call on the webpage. Initially though, there are no outwards API calls either to Db or external services.

How to solve "Router.use() requires a middleware function but got a Object at Function.use" error

I am getting an error when calling my router from my routes directory.I have made some changes in my code around some of the other posts on this issue but I can't get anything to solve.However i am not sure what exactly is wrong with my code below.
This is my error
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
E:\Program Files\mean apps\shoppinglist\crud-backend\node_modules\express\lib\router\index.js:458
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a Object
at Function.use (E:\Program Files\mean apps\shoppinglist\crud-backend\node_modules\express\lib\router\index.js:458:13)
at Function.<anonymous> (E:\Program Files\mean apps\shoppinglist\crud-backend\node_modules\express\lib\application.js:220:21)
at Array.forEach (<anonymous>)
at Function.use (E:\Program Files\mean apps\shoppinglist\crud-backend\node_modules\express\lib\application.js:217:7)
at Object.<anonymous> (E:\Program Files\mean apps\shoppinglist\crud-backend\app.js:42:5)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:279:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:752:3)
[nodemon] app crashed - waiting for file changes before starting...
I have this code in my app.js
//importing modules
var express = require('express');
var mongoose = require('mongoose');
var bodyparser = require('body-parser');
var cors = require('cors');
var path = require('path');
var app = express();
const route = require('./routes/route');
//conect to the mongodb
mongoose.connect('mongodb://localhost:27017/shoppinglist');
//on connection
mongoose.connection.on('connected',()=>{
console.log('Connected to database mongodb # 27017');
});
//error
mongoose.connection.on('error',(err)=>{
if(err)
{
console.log('Error in database connection:'+ err);
}
});
//port no
const port = 3000;
//adding middleware - cors
app.use(cors());
//body - parser
app.use(bodyparser.json());
//static files
app.use(express.static(path.join(__dirname, 'public')));
//routes
app.use('/api', route);
//testing server
app.get('/',(req, res)=>{
res.send('foobar');
});
app.listen(port,()=>{
console.log('Server started at port:' + port);
});
I have this code in my route.js
const express = require('express');
const router = express.Router();
const Item = require('../model/shoppingItem');
//retriving data from db
router.get('/items', (req, res, next)=>{
Item.find(function(err, items){
if(err){
res.json(err);
}
else{
res.json(items);
}
});
});
//insert data
router.post('item', (req, res, next)=>{
let newShoppingItem = new Item({
itemName: req.body.itemName,
itemQuantity: req.body.itemQuantity,
itemBought: req.body.itemBought
});
newShoppingItem.save((err, item)=>{
if(err){
res.json(err);
}
else{
res.json({msg: 'Item has been added successfully'});
}
});
});
You are using a module that you never exported.
app.use('/api', route);
but route was never exported - that's your main issue.
in your route module you can wrap everything in export default - alternatively you can use module.exports = router
This is an open source project I was working on try following the structure, if you still have issues let me know.
https://github.com/Muhand/nodejs-server

Express JS REST API with MySQL

I am doing an exercise with Express.js and MySQL. At the moment I have 4 files. The error is,
TypeError: areas.getAreas is not a function
at Object.<anonymous> (/--/--/--/src/routes/userRoutes.js:4:13)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/--/--/--/src/app.js:10:20)
at Module._compile (module.js:653:30)
But I am sure I am declaring the variable and function so, I don't understand why is it happening.
I tried to get the value of the variable areas in the userRoutes.js file but console just show me an "{}". I also tried to change the sintaxis of the function of the areas.js file, writing it as function and not like an object.
The main file is, app.js and it contains:
const express = require('express');
const app = express();
const morgan = require('morgan');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = require('/--/--/--/db/connection.js');
const userRoutes = require('/--/--/--/routes/userRoutes.js');
app.set('port', process.env.PORT || 3000);
app.use(morgan('dev'));
app.use(bodyParser.json());
connection(mysql);
userRoutes(app);
app.listen(app.get('port'), ()=> {
console.log('server on port 3000');
});
The next files are:
connection.js
'use strict';
module.exports = function connection(mysql){
mysql.createConnection({
host: 'http://x.x.x.x',
user: 'xxxxxxx',
password: 'xxxxxxx',
database: 'xxxxxxx'
})
};
areas.js
'use strict';
let areasModel = {};
areasModel.getAreas = (callback) => {
if(connection) {
connection.query(
"SELECT * FROM areas",
(err, rows) => {
if(err) {
throw err;
}
else {
callback(null, rows);
}
}
);
}
};
module.exports = areasModel;
userRoutes.js
'use strict';
const areas = require('../models/areas');
module.exports = function (app) {
app.get("/", (req,res)=>{
areas.getAreas((err, data) => {
res.json([]);
});
});
}
try importing connection.js in areas.js,
maybe because never enter in that if statement, returns undefined

socket io .use() is not a function

Im trying to use sessions middleware to connect express and socket.io
However i get this error:
io.use(function(socket, next){
^
TypeError: io.use is not a function
at Object.<anonymous> (/home/ubuntu/workspace/newserver.js:30:4)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:990:3
Here is my code:
var http = require('http');
var path = require('path');
var async = require('async');
var express = require('express');
var socketio = require('socket.io');
var sessions = require('express-session');
var mysql = require('mysql');
var RedisStore = require('connect-redis')(sessions);
var bodyParser = require('body-parser');
// App declaration
var router = express();
var server = http.createServer(router);
var io = socketio.listen(server);
io.set('log level',0);
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({extended:true}));
var sessionMiddleware = sessions({
store: new RedisStore({}),
secret: '901uj0394-0i4-#',
resave:true,
saveUninitialized:true
});
router.use(sessionMiddleware);
var session;
var appConfig = {
title: 'The Warring States 2'
};
router.set('views', path.resolve(__dirname,'client/views'));
router.set('view engine', 'pug');
var connection = mysql.createConnection({
// SQL Information
host: 'localhost',
user: 'boyton',
password: '',
database: 'WarringStates'
});
connection.connect(function(error){
// callback
if(!!error) {
console.log('Error!');
console.log(error);
}
else {
console.log('Connected to the database');
}
});
// Socket
var sockets = [];
var gamelobbies = [];
Im only starting out with node and expresss, I created a c9 container for node and installed the default Packages to work with the stack, Ive "tried" to update node and npm and express as well. However im not sure if they're up to the latest versions
here is what i get when i invoke check-node-versions
node: 4.7.3
npm: 2.15.11
yarn: not installed
express version 3.6.2
any help and input would be great. Thanks guys.
Change this line:
var io = socketio.listen(server);
to this:
// create an instance of socket.io, bound to our web werver
var io = socketio(server);
And, then make sure you have this somewhere:
// start the web server
server.listen(80);
The socketio library is a constructor and it wants you to call it and pass it the server to create the io object (an instance of the socket.io server). You then separately start the server so it can be used for both your http requests and your socket.io requests.
The way you were doing it, socketio was not the right kind of object to call .listen() on. It was the module handle rather than an instance and thus io was the wrong kind of object and thus why there was no .use() method.

Categories

Resources