Facebook Pixel

DevTinder Common Bugs and Solutions Debugging Guide for Node.js Projects

Learn how to debug and fix common bugs in the DevTinder project from MongoDB connection issues and JWT errors to Socket.io disconnections and CORS problems.

DevTinder Common Bugs and Solutions

Building DevTinder teaches you to debug real-world Node.js issues. This guide covers the most common bugs and their solutions.

1. MongoDB Connection Failed

Symptom: Server starts but MongoDB connection throws an error.

Cause: MongoDB isn't running, wrong connection string, or network issues.

Solution:

# Check if local MongoDB is running mongosh # For Atlas, verify: # - IP is whitelisted (0.0.0.0/0 for dev) # - Username and password are correct # - Connection string format is right

Check your .env:

MONGODB_URI=mongodb+srv://username:[email protected]/devtinder

Ensure the database name is in the URI (e.g., /devtinder at the end).

2. JWT Token Errors

Symptom: JsonWebTokenError: invalid signature or TokenExpiredError.

Cause: Wrong JWT secret, expired token, or malformed token.

Solution:

  • Ensure JWT_SECRET is the same across all environments
  • Check token expiration in jwt.sign(): expiresIn: "7d"
  • For expired tokens, the frontend should redirect to login on 401
  • Use the auth middleware to catch and return proper 401 errors

3. CORS Errors

Symptom: Frontend gets Access-Control-Allow-Origin error in browser console.

Cause: Backend CORS configuration doesn't allow the frontend origin.

Solution:

app.use(cors({ origin: process.env.CLIENT_URL, // e.g., http://localhost:5173 credentials: true // critical for cookies }));

Ensure CLIENT_URL in backend .env matches the frontend URL exactly (including port).

4. Cookie Not Being Set

Symptom: Login succeeds but the cookie isn't set in the browser.

Cause: Missing withCredentials on frontend, wrong cookie options, or HTTPS/HTTP mismatch.

Solution:

Frontend (Axios):

axios.defaults.withCredentials = true;

Backend (cookie options):

res.cookie("token", token, { httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "lax", // or "none" if cross-site with secure: true maxAge: 7 * 24 * 60 * 60 * 1000 });

Note: sameSite: "none" requires secure: true (HTTPS only).

5. Socket.io Connection Failed

Symptom: Frontend can't connect to Socket.io, or messages aren't being received.

Cause: CORS issues, missing auth token, or Nginx not configured for WebSockets.

Solution:

Backend:

const io = socketio(server, { cors: { origin: process.env.CLIENT_URL, credentials: true } });

Frontend:

const socket = io(SOCKET_URL, { withCredentials: true, auth: { token: getCookie("token") } });

Nginx (for production):

location /socket.io/ { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }

6. Duplicate Key Error (11000)

Symptom: E11000 duplicate key error collection when creating a user or connection request.

Cause: Trying to insert a document with a unique field that already exists.

Solution:

// In the global error handler if (err.code === 11000) { const field = Object.keys(err.keyPattern)[0]; return res.status(409).json({ message: `Duplicate value for ${field}` }); }

For users, it's usually a duplicate email. For connection requests, it's a duplicate request pair.

7. Feed Shows Connected Users

Symptom: The feed includes users that have already been connected or requested.

Cause: The exclusion query ($nin) is not working correctly.

Solution: Ensure you're collecting ALL user IDs from connection requests (both sent and received):

const requests = await ConnectionRequest.find({ $or: [ { fromUserId: userId }, { toUserId: userId } ] }); const hiddenIds = new Set([userId.toString()]); requests.forEach(req => { hiddenIds.add(req.fromUserId.toString()); hiddenIds.add(req.toUserId.toString()); }); const feed = await User.find({ _id: { $nin: [...hiddenIds] } });

8. Populate Returns Null

Symptom: populate() returns null for a referenced field.

Cause: The referenced ObjectId doesn't exist in the referenced collection, or the model name in ref is wrong.

Solution:

  • Check that the ref value matches the model name exactly
  • Verify the referenced document exists in the database
  • Use populate("field", "selectedFields") to avoid fetching unnecessary data

9. Password Not Hashed on Update

Symptom: Updating a user's password saves it in plain text.

Cause: findByIdAndUpdate doesn't trigger pre-save hooks.

Solution: Use save() instead of findByIdAndUpdate for password changes:

const user = await User.findById(req.user._id); user.password = newPassword; await user.save(); // triggers pre-save hash hook

10. Nginx 502 Bad Gateway

Symptom: Nginx returns 502 Bad Gateway.

Cause: The Node.js app isn't running, or Nginx is proxying to the wrong port.

Solution:

# Check if PM2 process is running pm2 status # Check PM2 logs for errors pm2 logs devtinder-api # Verify Nginx proxy_pass matches app port sudo cat /etc/nginx/sites-enabled/devtinder # Restart both pm2 restart devtinder-api sudo systemctl restart nginx

The Takeaway

Common DevTinder bugs include MongoDB connection issues, JWT errors, CORS and cookie configuration problems, Socket.io connection failures, duplicate key errors, and populate returning null. The key to debugging is reading error messages carefully, checking environment variables, and using logs (PM2 logs, Nginx logs, browser console) to trace the issue.

Check if MongoDB is running (mongosh for local), verify the MONGODB_URI in .env, ensure Atlas IP whitelist includes your IP, and check that the database name is in the connection string.

Ensure the frontend uses withCredentials: true in Axios, the backend sets credentials: true in CORS, and cookie options include httpOnly: true, sameSite: 'lax', and secure: true only in production (HTTPS). sameSite: 'none' requires secure: true.

Configure CORS on the backend Socket.io server with the frontend origin and credentials: true. On the frontend, use withCredentials: true and pass the token in auth. In production, configure Nginx with Upgrade and Connection headers for WebSocket support.

In the global error handler, check if err.code === 11000. Extract the field name from err.keyPattern and return a 409 Conflict status with a descriptive message like 'Duplicate value for email'.

The referenced ObjectId doesn't exist in the referenced collection, or the ref value in the schema doesn't match the model name. Check that the ref string matches the model name exactly and verify the referenced document exists.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.