Skip to content

Commit ee0092d

Browse files
authored
Merge pull request #15 from techstartucalgary/reconstruct-backend-pipeline
fix async in index.js for deployment
2 parents c18294c + 3a8ef8f commit ee0092d

File tree

5 files changed

+81
-83
lines changed

5 files changed

+81
-83
lines changed

shatter-backend/api/index.ts

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,59 @@ import app from '../src/app';
44

55
const MONGODB_URI = process.env.MONGO_URI;
66

7-
let cachedConnection: typeof mongoose | null = null;
7+
let isConnected = false;
88

99
async function connectDB() {
10-
if (cachedConnection) {
11-
return cachedConnection;
10+
if (isConnected && mongoose.connection.readyState === 1) {
11+
console.log('Using existing MongoDB connection');
12+
return;
1213
}
1314

1415
if (!MONGODB_URI) {
1516
throw new Error('MONGO_URI is not set in environment variables');
1617
}
1718

18-
const conn = await mongoose.connect(MONGODB_URI, {
19-
bufferCommands: false,
20-
});
21-
22-
cachedConnection = conn;
23-
return conn;
19+
try {
20+
console.log('Creating new MongoDB connection...');
21+
22+
await mongoose.connect(MONGODB_URI, {
23+
bufferCommands: false,
24+
maxPoolSize: 10,
25+
serverSelectionTimeoutMS: 5000,
26+
socketTimeoutMS: 45000,
27+
});
28+
29+
isConnected = true;
30+
console.log('MongoDB connected successfully');
31+
32+
mongoose.connection.on('error', (err) => {
33+
console.error('MongoDB connection error:', err);
34+
isConnected = false;
35+
});
36+
37+
mongoose.connection.on('disconnected', () => {
38+
console.log('MongoDB disconnected');
39+
isConnected = false;
40+
});
41+
42+
} catch (error) {
43+
console.error('Failed to connect to MongoDB:', error);
44+
isConnected = false;
45+
throw error;
46+
}
2447
}
2548

26-
connectDB().catch((err) => {
27-
console.error('Failed to connect to MongoDB:', err);
49+
app.use(async (req, res, next) => {
50+
try {
51+
await connectDB();
52+
next();
53+
} catch (error: any) {
54+
console.error('Database connection error:', error);
55+
res.status(500).json({
56+
error: 'Database connection failed',
57+
details: process.env.NODE_ENV === 'development' ? error.message : undefined
58+
});
59+
}
2860
});
2961

3062
export default app;

shatter-backend/src/app.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,14 @@
1-
// Express framework gives us fucnctions to creeate web server, handle routes, process HTTP req and send responses
21
import express from 'express';
3-
import userRoutes from './routes/user_route'; // these routes define how to handel requests to /api/users
2+
import userRoutes from './routes/user_route';
43

5-
// Creating express application as a single "app" object, started in server.ts
6-
// This object represents entire web server and will be used to:
7-
// register Middleware, define routes ....
84
const app = express();
95

10-
// Middleware setup
11-
// responsible for parsing incoming JSON request bodies, making req.body usable in controllers
126
app.use(express.json());
137

14-
// Defining routes
15-
// a simple route that sends back plain text "Hello" when anyone visits the app in browser
168
app.get('/', (_req, res) => {
179
res.send('Hello');
1810
});
1911

20-
// Mounts the user routes under the path 'api/users'
21-
// any routes defined in user_route.ts will be accessible with URLs starting with /api/users
2212
app.use('/api/users', userRoutes);
2313

24-
25-
// Export the configured Express app, so that server.ts can import it
26-
// Keeping app setup separate from server startup makes the code modular and testable
2714
export default app;
Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,41 @@
1-
// import req and res types for type safety
2-
import { Request, Response } from 'express';
3-
import { User } from '../models/user_model'; // imports user model created with mongoose
1+
import { Request, Response } from "express";
2+
import { User } from "../models/user_model";
43

54
// controller: GET /api/users
65
// This function handles GET reqs to /api/users
76
// It fetches all users from MongoDB and sends them as json
87

98
export const getUsers = async (_req: Request, res: Response) => {
10-
try {
11-
// retrieves all docs from "users" collection
12-
const users = await User.find().lean(); // .lean() returns plain JS objects instead of Mongoose docs, may change incase we need extra model methods later
13-
res.json(users); // sends list of users back as JSON response
14-
} catch (err) { // log the error if something goes wrong
15-
console.error('GET /api/users error:', err);
16-
res.status(500).json({ error: 'Failed to fetch users' });
17-
}
9+
try {
10+
const users = await User.find().lean();
11+
res.json(users);
12+
} catch (err: any) {
13+
console.error("GET /api/users error:", err);
14+
res.status(500).json({
15+
error: "Failed to fetch users",
16+
message: err.message,
17+
});
18+
}
1819
};
1920

20-
2121
// controller: POST /api/users
2222
// reads data from req body, vailidates it and creates a new user
2323
export const createUser = async (req: Request, res: Response) => {
24-
try {
25-
// Destructure the req body sent by the client
26-
// The ?? {} ensures we don't get error if req.body is undefined
27-
const { name, email } = req.body ?? {};
24+
try {
25+
const { name, email } = req.body ?? {};
2826

29-
// Basic validation to ensure both name and email are provided
30-
// if not respond with bad request and stop further processes
31-
if (!name || !email) {
32-
return res.status(400).json({ error: 'name and email required' });
33-
}
27+
if (!name || !email) {
28+
return res.status(400).json({ error: "name and email required" });
29+
}
3430

35-
// create a new user doc in DB using Mongoose's .create()
36-
const user = await User.create({ name, email });
37-
// respond with "created" and send back created user as JSON
38-
res.status(201).json(user);
39-
} catch(err: any) {
40-
// Handle duplicate email error
41-
// Mongo DB rejects duplicat value since we have email marked as 'unique'
42-
if (err?.code === 11000) {
43-
return res.status(409).json({ error: 'email already exists' });
44-
}
45-
46-
// for all other errors, log them and return generic 500 response
47-
console.error('POST /api/users error:', err);
48-
res.status(500).json({error: 'Failed to create user' });
31+
const user = await User.create({ name, email });
32+
res.status(201).json(user);
33+
} catch (err: any) {
34+
if (err?.code === 11000) {
35+
return res.status(409).json({ error: "email already exists" });
4936
}
37+
38+
console.error("POST /api/users error:", err);
39+
res.status(500).json({ error: "Failed to create user" });
40+
}
5041
};
Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
1-
// router is like a mini-express app that allows grouping of related routes together
21
import { Router } from 'express';
32
import { getUsers, createUser } from '../controllers/user_controller';
4-
// Importing controller functions that handle logic for each route
5-
// These function define what happens when a req is received
63

7-
// creating new router instance
84
const router = Router();
95

10-
// Defining routes for the /api/users path
11-
router.get('/', getUsers); // when GET req is made, run getUsers func
12-
router.post('/', createUser); // when POST req is made, run creatUser func
6+
router.get('/', getUsers);
7+
router.post('/', createUser);
138

14-
// Export the router so it can be used in app.ts
15-
// app.ts imports router and mounts it under '/api/users'
169
export default router;

shatter-backend/src/server.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,26 @@
1-
// This is the main entry point that starts the application
2-
3-
import 'dotenv/config'; // loads .env file and populates process.env (the node.js object)
4-
import mongoose from 'mongoose'; // mongoose is an Object Data Modelling (ODM) livrary for MongoDB
5-
import app from './app'; // Import the express app
6-
1+
import 'dotenv/config';
2+
import mongoose from 'mongoose';
3+
import app from './app';
74

85
// config
6+
const PORT = process.env.PORT ? Number(process.env.PORT) : 4000;
7+
const MONGODB_URI = process.env.MONGO_URI;
98

10-
const PORT = process.env.PORT ? Number(process.env.PORT) : 4000; // use defined PORT in .env if present , otherwise default to 400
11-
const MONGODB_URI = process.env.MONGO_URI; // read the mongoDB connection from env variables
12-
13-
// Start up function
149
async function start() {
1510
try {
16-
if (!MONGODB_URI) { // check that MOGO URI is provided in .env
11+
if (!MONGODB_URI) {
1712
throw new Error('MONGODB_URI is not set');
1813
}
19-
await mongoose.connect(MONGODB_URI); // this returns a promise, so we 'await' until it's successfully connected
14+
await mongoose.connect(MONGODB_URI);
2015
console.log('Successfully connected to MongoDB');
2116

2217
// start listening for incoming HTTP requests on chosen port
2318
app.listen(PORT, () => {
2419
console.log('Server running on http://localhost:${PORT}');
2520
});
26-
} catch (err) { // if connection goes wrong, log the error
21+
} catch (err) {
2722
console.error('Failed to start server:', err);
28-
process.exit(1); // code 1 indicates failure
23+
process.exit(1);
2924
}
3025
}
3126

0 commit comments

Comments
 (0)