From 30ce6261f6e287dd6f7f15a7919b304efda85144 Mon Sep 17 00:00:00 2001 From: abdeyali Date: Wed, 30 Jul 2025 23:51:36 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Implement=20error=20handling=20for?= =?UTF-8?q?=20backend=20APIs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/models/User.js | 59 +++++++++++++++++++++++------------------- backend/routes/auth.js | 53 ++++++++++++++++++++++++++----------- backend/server.js | 44 +++++++++++++++++++++++-------- 3 files changed, 103 insertions(+), 53 deletions(-) diff --git a/backend/models/User.js b/backend/models/User.js index 779294f..8568df4 100644 --- a/backend/models/User.js +++ b/backend/models/User.js @@ -2,39 +2,44 @@ const mongoose = require("mongoose"); const bcrypt = require("bcryptjs"); const UserSchema = new mongoose.Schema({ - username: { - type: String, - required: true, - unique: true, - }, - email: { - type: String, - required: true, - unique: true, - }, - password: { - type: String, - required: true, - }, -}); - -UserSchema.pre('save', async function (next) { + username: { + type: String, + required: [true, "Username is required"], + unique: true, + trim: true, + }, + email: { + type: String, + required: [true, "Email is required"], + unique: true, + trim: true, + lowercase: true, + match: [/.+\@.+\..+/, "Please enter a valid email address"], + }, + password: { + type: String, + required: [true, "Password is required"], + minlength: [6, "Password must be at least 6 characters long"], + }, +}, { timestamps: true }); - if (!this.isModified('password')) - return next(); +// Pre-save password hash +UserSchema.pre("save", async function (next) { + if (!this.isModified("password")) return next(); - try { - const salt = await bcrypt.genSalt(10); - this.password = await bcrypt.hash(this.password, salt); - next(); - } catch (err) { - return next(err); - } + try { + const salt = await bcrypt.genSalt(10); + this.password = await bcrypt.hash(this.password, salt); + return next(); + } catch (err) { + console.error("Password Hashing Error:", err.message); + return next(err); + } }); // Compare passwords during login UserSchema.methods.comparePassword = async function (enteredPassword) { - return await bcrypt.compare(enteredPassword, this.password); + return await bcrypt.compare(enteredPassword, this.password); }; module.exports = mongoose.model("User", UserSchema); diff --git a/backend/routes/auth.js b/backend/routes/auth.js index e26c7a9..f277383 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -5,37 +5,60 @@ const router = express.Router(); // Signup route router.post("/signup", async (req, res) => { - - const { username, email, password } = req.body; + const { username, email, password } = req.body; try { - const existingUser = await User.findOne( {email} ); + const existingUser = await User.findOne({ email }); - if (existingUser) - return res.status(400).json( {message: 'User already exists'} ); + if (existingUser) { + return res.status(400).json({ message: 'User already exists' }); + } - const newUser = new User( {username, email, password} ); + const newUser = new User({ username, email, password }); await newUser.save(); - res.status(201).json( {message: 'User created successfully'} ); + + return res.status(201).json({ message: 'User created successfully' }); } catch (err) { - res.status(500).json({ message: 'Error creating user', error: err.message }); + console.error("Signup Error:", err.message); + return res.status(500).json({ + message: 'Error creating user', + error: err.message + }); } }); // Login route -router.post("/login", passport.authenticate('local'), (req, res) => { - res.status(200).json( { message: 'Login successful', user: req.user } ); +router.post("/login", (req, res, next) => { + passport.authenticate('local', (err, user, info) => { + if (err) { + console.error("Login Error:", err.message); + return res.status(500).json({ message: 'Internal Server Error', error: err.message }); + } + + if (!user) { + return res.status(401).json({ message: 'Invalid credentials', error: info?.message || 'Authentication failed' }); + } + + req.logIn(user, (err) => { + if (err) { + console.error("Session Error:", err.message); + return res.status(500).json({ message: 'Login failed', error: err.message }); + } + + return res.status(200).json({ message: 'Login successful', user }); + }); + })(req, res, next); }); // Logout route router.get("/logout", (req, res) => { - req.logout((err) => { - - if (err) + if (err) { + console.error("Logout Error:", err.message); return res.status(500).json({ message: 'Logout failed', error: err.message }); - else - res.status(200).json({ message: 'Logged out successfully' }); + } + + return res.status(200).json({ message: 'Logged out successfully' }); }); }); diff --git a/backend/server.js b/backend/server.js index 3f19f00..846bff4 100644 --- a/backend/server.js +++ b/backend/server.js @@ -11,29 +11,51 @@ require('./config/passportConfig'); const app = express(); -// CORS configuration -app.use(cors('*')); +// ✅ CORS configuration (recommended) +app.use(cors({ + origin: '*', // You can replace * with specific domains in production + credentials: true, +})); -// Middleware +// ✅ Middleware app.use(bodyParser.json()); + app.use(session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, })); + app.use(passport.initialize()); app.use(passport.session()); -// Routes +// ✅ Routes const authRoutes = require('./routes/auth'); app.use('/api/auth', authRoutes); -// Connect to MongoDB -mongoose.connect(process.env.MONGO_URI, {}).then(() => { - console.log('Connected to MongoDB'); - app.listen(process.env.PORT, () => { - console.log(`Server running on port ${process.env.PORT}`); +// ✅ Fallback route for 404 Not Found +app.use((req, res, next) => { + res.status(404).json({ message: 'Route not found' }); +}); + +// ✅ Global error-handling middleware +app.use((err, req, res, next) => { + console.error('Unhandled Error:', err.stack); + res.status(err.status || 500).json({ + message: err.message || 'Internal Server Error', + error: process.env.NODE_ENV === 'production' ? undefined : err.stack, }); -}).catch((err) => { - console.log('MongoDB connection error:', err); }); + +// ✅ Connect to MongoDB and start server +mongoose.connect(process.env.MONGO_URI, {}) + .then(() => { + console.log('Connected to MongoDB'); + app.listen(process.env.PORT, () => { + console.log(`Server running on port ${process.env.PORT}`); + }); + }) + .catch((err) => { + console.error('MongoDB connection error:', err); + process.exit(1); // exit the process on DB failure + });