From bd1c37f453e72e8a386b56625d48d8dc62c583a2 Mon Sep 17 00:00:00 2001 From: "jawher.kallel" Date: Thu, 6 Feb 2025 10:04:31 +0100 Subject: [PATCH] update all controllers with using to avoid using try catch everything --- controllers/authController.js | 86 ++++++++++++-------------- controllers/metricsController.js | 83 ++++++++++--------------- controllers/userController.js | 101 +++++++++++++------------------ package-lock.json | 10 +++ package.json | 1 + 5 files changed, 123 insertions(+), 158 deletions(-) diff --git a/controllers/authController.js b/controllers/authController.js index 608c634..43a7330 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -1,3 +1,4 @@ +require('express-async-errors'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const pool = require('../config/db'); @@ -6,62 +7,53 @@ const register = async (req, res, next) => { const { name, email, password } = req.body; const hashedPassword = await bcrypt.hash(password, 10); - try { - const result = await pool.query( - 'INSERT INTO users (name, email, password) VALUES ($1, $2, $3) RETURNING id', - [name, email, hashedPassword] - ); - res.status(201).json({ message: 'User registered', userId: result.rows[0].id }); - } catch (error) { - next(error); - } + const result = await pool.query( + 'INSERT INTO users (name, email, password) VALUES ($1, $2, $3) RETURNING id', + [name, email, hashedPassword] + ); + res.status(201).json({ message: 'User registered', userId: result.rows[0].id }); }; const login = async (req, res) => { const { email, password } = req.body; - try { - // Input validation - if (!email || !password) { - return res.status(400).json({ message: 'Email and password are required' }); - } - - // Check if the user exists - const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]); - const user = result.rows[0]; - - if (!user) { - return res.status(401).json({ message: 'Invalid email or password' }); - } + // Input validation + if (!email || !password) { + return res.status(400).json({ message: 'Email and password are required' }); + } - // Compare password with hashed password in database - const passwordMatch = await bcrypt.compare(password, user.password); - if (!passwordMatch) { - return res.status(401).json({ message: 'Invalid email or password' }); - } + // Check if the user exists + const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]); + const user = result.rows[0]; - // Generate a JWT token including user role - const token = jwt.sign( - { userId: user.id, email: user.email, role: user.role }, // Include role in payload - process.env.JWT_SECRET, - { expiresIn: '1h' } // Token expiration - ); + if (!user) { + return res.status(401).json({ message: 'Invalid email or password' }); + } - // Response with token and user details - res.status(200).json({ - message: 'Login successful', - token, - user: { - id: user.id, - name: user.name, - email: user.email, - role: user.role, - }, - }); - } catch (error) { - console.error('Login error:', error); - res.status(500).json({ message: 'Server error during login' }); + // Compare password with hashed password in database + const passwordMatch = await bcrypt.compare(password, user.password); + if (!passwordMatch) { + return res.status(401).json({ message: 'Invalid email or password' }); } + + // Generate a JWT token including user role + const token = jwt.sign( + { userId: user.id, email: user.email, role: user.role }, // Include role in payload + process.env.JWT_SECRET, + { expiresIn: '1h' } // Token expiration + ); + + // Response with token and user details + res.status(200).json({ + message: 'Login successful', + token, + user: { + id: user.id, + name: user.name, + email: user.email, + role: user.role, + }, + }); }; module.exports = { register, login }; diff --git a/controllers/metricsController.js b/controllers/metricsController.js index 0c0d847..7a007b2 100644 --- a/controllers/metricsController.js +++ b/controllers/metricsController.js @@ -1,3 +1,4 @@ +require('express-async-errors'); const Metrics = require('../models/metrics'); const client = require('prom-client'); const jwt = require('jsonwebtoken'); @@ -34,40 +35,36 @@ const getMetrics = async (req, res) => { }; */ +// Metrics endpoint handler const getMetrics = async (req, res) => { - try { - // Get the Authorization header - const authHeader = req.headers['authorization']; - if (!authHeader || !authHeader.startsWith('Bearer ')) { - return res.status(401).json({ error: 'Unauthorized: No token provided' }); - } + // Get the Authorization header + const authHeader = req.headers['authorization']; + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return res.status(401).json({ error: 'Unauthorized: No token provided' }); + } - // Extract the token - const token = authHeader.split(' ')[1]; + // Extract the token + const token = authHeader.split(' ')[1]; - // Verify and decode the token - const decoded = jwt.verify(token, process.env.JWT_SECRET); - const userId = decoded.userId; // Ensure your JWT payload contains a `userId` + // Verify and decode the token + const decoded = jwt.verify(token, process.env.JWT_SECRET); + const userId = decoded.userId; // Ensure your JWT payload contains a `userId` - if (!userId) { - return res.status(400).json({ error: 'Invalid token: userId missing' }); - } + if (!userId) { + return res.status(400).json({ error: 'Invalid token: userId missing' }); + } - // Set content type and retrieve metrics - res.set('Content-Type', register.contentType); - const metricsText = await register.metrics(); - const metrics = parseMetrics(metricsText); // Helper function to parse metrics. + // Set content type and retrieve metrics + res.set('Content-Type', register.contentType); + const metricsText = await register.metrics(); + const metrics = parseMetrics(metricsText); // Helper function to parse metrics. - // Save metrics to the database - await Metrics.saveMetricsToDatabase(userId, metrics); + // Save metrics to the database + await Metrics.saveMetricsToDatabase(userId, metrics); - // Send the metrics as a response - res.set('Content-Type', register.contentType); - res.send(metricsText); - } catch (error) { - console.error("Error in getMetrics:", error); - res.status(500).send({ error: "Failed to process metrics" }); - } + // Send the metrics as a response + res.set('Content-Type', register.contentType); + res.send(metricsText); }; function parseMetrics(metricsText) { @@ -90,43 +87,27 @@ function parseMetrics(metricsText) { const createMetric = async (req, res) => { const { userId, metricName, metricValue } = req.body; - try { - const metric = await Metrics.create({ userId, metricName, metricValue }); - res.status(201).json(metric); - } catch (error) { - res.status(500).json({ error: 'Failed to create metric' }); - } + const metric = await Metrics.create({ userId, metricName, metricValue }); + res.status(201).json(metric); }; const getMetricsByUser = async (req, res) => { const { userId } = req.params; - try { - const metrics = await Metrics.findByUserId(userId); - res.status(200).json(metrics); - } catch (error) { - res.status(500).json({ error: 'Failed to fetch metrics' }); - } + const metrics = await Metrics.findByUserId(userId); + res.status(200).json(metrics); }; const updateMetric = async (req, res) => { const { id } = req.params; const { metricName, metricValue } = req.body; - try { - const metric = await Metrics.update(id, { metricName, metricValue }); - res.status(200).json(metric); - } catch (error) { - res.status(500).json({ error: 'Failed to update metric' }); - } + const metric = await Metrics.update(id, { metricName, metricValue }); + res.status(200).json(metric); }; const deleteMetric = async (req, res) => { const { id } = req.params; - try { - await Metrics.delete(id); - res.status(200).json({ message: 'Metric deleted successfully' }); - } catch (error) { - res.status(500).json({ error: 'Failed to delete metric' }); - } + await Metrics.delete(id); + res.status(200).json({ message: 'Metric deleted successfully' }); }; module.exports = { diff --git a/controllers/userController.js b/controllers/userController.js index 8cb820e..22315d0 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -1,3 +1,4 @@ +require('express-async-errors'); const User = require('../models/user'); const Joi = require('joi'); const logger = require('../utils/logger'); @@ -9,47 +10,35 @@ const userSchema = Joi.object({ password: Joi.string().min(8).required(), }); -const getUsers = async (req, res, next) => { - try { - const users = await User.getAll(req.query); - res.status(200).json(users); - } catch (error) { - next(error); - } +const getUsers = async (req, res) => { + const users = await User.getAll(req.query); + res.status(200).json(users); }; -const getUserById = async (req, res, next) => { - try { - const userId = parseInt(req.params.id, 10); // Ensure userId is a number - if (isNaN(userId)) { - return res.status(400).json({ error: 'Invalid user ID' }); - } - const user = await User.getById(userId); - if (!user) return res.status(404).json({ message: 'User not found' }); - res.status(200).json(user); - } catch (error) { - next(error); +const getUserById = async (req, res) => { + const userId = parseInt(req.params.id, 10); // Ensure userId is a number + if (isNaN(userId)) { + return res.status(400).json({ error: 'Invalid user ID' }); } + const user = await User.getById(userId); + if (!user) return res.status(404).json({ message: 'User not found' }); + res.status(200).json(user); }; -const createUser = async (req, res, next) => { - try { - const { error, value } = userSchema.validate(req.body); - if (error) { - return res.status(400).json({ error: error.details[0].message }); - } - if (!req.file) { - return res.status(400).json({ error: "Profile picture is required" }); - } - value.picture = req.file.filename; // Add uploaded filename to user data - const userId = await User.create(value); - res.status(201).json({ message: "User added", userId }); - } catch (error) { - next(error); +const createUser = async (req, res) => { + const { error, value } = userSchema.validate(req.body); + if (error) { + return res.status(400).json({ error: error.details[0].message }); + } + if (!req.file) { + return res.status(400).json({ error: "Profile picture is required" }); } + value.picture = req.file.filename; // Add uploaded filename to user data + const userId = await User.create(value); + res.status(201).json({ message: "User added", userId }); }; -const updateUser = async (req, res, next) => { +const updateUser = async (req, res) => { const { id } = req.params; const { name, email, password } = req.body; @@ -57,28 +46,24 @@ const updateUser = async (req, res, next) => { return res.status(400).json({ error: 'Invalid email format' }); } - try { - const user = await User.getById(id); - if (!user) { - return res.status(404).json({ error: 'User not found' }); - } + const user = await User.getById(id); + if (!user) { + return res.status(404).json({ error: 'User not found' }); + } - // Assuming `User.update` returns the updated user - await User.update(id, { name, email, password }); + // Assuming `User.update` returns the updated user + await User.update(id, { name, email, password }); - // If `User.update` doesn't return the full user object, fetch it again - const updatedUserDetails = await User.getById(id); + // If `User.update` doesn't return the full user object, fetch it again + const updatedUserDetails = await User.getById(id); - return res.status(200).json({ - message: `User modified with ID: ${id}`, - user: updatedUserDetails, // return the updated user object - }); - } catch (error) { - next(error); - } + return res.status(200).json({ + message: `User modified with ID: ${id}`, + user: updatedUserDetails, // return the updated user object + }); }; -const deleteUser = async (req, res, next) => { +const deleteUser = async (req, res) => { const { id } = req.params; // Ensure that the ID is a valid integer @@ -86,17 +71,13 @@ const deleteUser = async (req, res, next) => { return res.status(400).json({ error: 'Invalid user ID format' }); } - try { - const user = await User.getById(id); // Check if the user exists - if (!user) { - return res.status(404).json({ error: 'User not found' }); - } - - await User.delete(id); // Proceed with the deletion - res.status(200).json({ message: `User soft deleted with ID: ${id}` }); - } catch (error) { - next(error); + const user = await User.getById(id); // Check if the user exists + if (!user) { + return res.status(404).json({ error: 'User not found' }); } + + await User.delete(id); // Proceed with the deletion + res.status(200).json({ message: `User soft deleted with ID: ${id}` }); }; module.exports = { diff --git a/package-lock.json b/package-lock.json index 276741a..ec4f8dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-async-errors": "^3.1.1", "express-rate-limit": "^7.4.1", "express-rate-limit-redis": "^0.0.4", "helmet": "^8.0.0", @@ -3973,6 +3974,15 @@ "node": ">= 0.10.0" } }, + "node_modules/express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "license": "ISC", + "peerDependencies": { + "express": "^4.16.2" + } + }, "node_modules/express-rate-limit": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.1.tgz", diff --git a/package.json b/package.json index e237df2..158f6a7 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", + "express-async-errors": "^3.1.1", "express-rate-limit": "^7.4.1", "express-rate-limit-redis": "^0.0.4", "helmet": "^8.0.0",