refactor: error handling messages and validation

This commit is contained in:
elangptra 2024-12-18 10:39:28 +07:00
parent a898e06b74
commit e50f666928
5 changed files with 183 additions and 31 deletions

View File

@ -31,6 +31,15 @@ export const registerAdmin = async (req, res) => {
return response(400, null, "Password is required!", res); return response(400, null, "Password is required!", res);
} }
if (PASSWORD.length < 8) {
return response(
400,
null,
"Password must be at least 8 characters long!",
res
);
}
if (!CONFIRM_PASSWORD) { if (!CONFIRM_PASSWORD) {
return response(400, null, "Confirm Password is required!", res); return response(400, null, "Confirm Password is required!", res);
} }
@ -63,6 +72,11 @@ export const registerAdmin = async (req, res) => {
} catch (error) { } catch (error) {
console.log(error); console.log(error);
if (error.name === "SequelizeValidationError") {
const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
if (error.name === "SequelizeUniqueConstraintError") { if (error.name === "SequelizeUniqueConstraintError") {
return response(400, null, "Email already registered!", res); return response(400, null, "Email already registered!", res);
} }
@ -90,6 +104,15 @@ export const registerTeacher = async (req, res) => {
return response(400, null, "Password is required!", res); return response(400, null, "Password is required!", res);
} }
if (PASSWORD.length < 8) {
return response(
400,
null,
"Password must be at least 8 characters long!",
res
);
}
if (!CONFIRM_PASSWORD) { if (!CONFIRM_PASSWORD) {
return response(400, null, "Confirm Password is required!", res); return response(400, null, "Confirm Password is required!", res);
} }
@ -272,21 +295,31 @@ export const registerTeacher = async (req, res) => {
response(200, null, "Teacher registered! Please verify your email.", res); response(200, null, "Teacher registered! Please verify your email.", res);
} catch (error) { } catch (error) {
console.log(error);
await transaction.rollback(); await transaction.rollback();
if (error.name === "SequelizeUniqueConstraintError") { if (error.name === "SequelizeValidationError") {
const field = error.original.sqlMessage.match(/for key '(.+)'/)[1]; const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
if (field === "teacher_unique_nip") { if (error.name === "SequelizeUniqueConstraintError") {
const tableMatch =
error.original.sqlMessage.match(/for key '(.+)\.(.+)'/);
const tableName = tableMatch ? tableMatch[1] : null;
const constraintName = tableMatch ? tableMatch[2] : null;
if (tableName === "users" && constraintName === "user_unique_email") {
return response(400, null, "Email already registered!", res);
}
if (tableName === "teacher" && constraintName === "teacher_unique_nip") {
return response(400, null, "NIP already registered!", res); return response(400, null, "NIP already registered!", res);
} }
if (field === "user_unique_email") { return response(400, null, "Unique constraint violation!", res);
return response(400, null, "Email already registered!", res);
}
} }
console.error(error);
response(500, null, "Internal Server Error", res); response(500, null, "Internal Server Error", res);
} }
}; };
@ -310,6 +343,15 @@ export const registerStudent = async (req, res) => {
return response(400, null, "Password is required!", res); return response(400, null, "Password is required!", res);
} }
if (PASSWORD.length < 8) {
return response(
400,
null,
"Password must be at least 8 characters long!",
res
);
}
if (!CONFIRM_PASSWORD) { if (!CONFIRM_PASSWORD) {
return response(400, null, "Confirm Password is required!", res); return response(400, null, "Confirm Password is required!", res);
} }
@ -492,21 +534,31 @@ export const registerStudent = async (req, res) => {
response(200, null, "Student registered! Please verify your email.", res); response(200, null, "Student registered! Please verify your email.", res);
} catch (error) { } catch (error) {
console.log(error);
await transaction.rollback(); await transaction.rollback();
if (error.name === "SequelizeUniqueConstraintError") { if (error.name === "SequelizeValidationError") {
const field = error.original.sqlMessage.match(/for key '(.+)'/)[1]; const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
if (field === "student_unique_nisn") { if (error.name === "SequelizeUniqueConstraintError") {
const tableMatch =
error.original.sqlMessage.match(/for key '(.+)\.(.+)'/);
const tableName = tableMatch ? tableMatch[1] : null;
const constraintName = tableMatch ? tableMatch[2] : null;
if (tableName === "users" && constraintName === "user_unique_email") {
return response(400, null, "Email already registered!", res);
}
if (tableName === "student" && constraintName === "student_unique_nisn") {
return response(400, null, "NISN already registered!", res); return response(400, null, "NISN already registered!", res);
} }
if (field === "user_unique_email") { return response(400, null, "Unique constraint violation!", res);
return response(400, null, "Email already registered!", res);
}
} }
console.error(error);
response(500, null, "Internal Server Error", res); response(500, null, "Internal Server Error", res);
} }
}; };
@ -545,6 +597,15 @@ export const registerTeacherForAdmin = async (req, res) => {
return response(400, null, "Password is required!", res); return response(400, null, "Password is required!", res);
} }
if (PASSWORD.length < 8) {
return response(
400,
null,
"Password must be at least 8 characters long!",
res
);
}
if (!CONFIRM_PASSWORD) { if (!CONFIRM_PASSWORD) {
return response(400, null, "Confirm Password is required!", res); return response(400, null, "Confirm Password is required!", res);
} }
@ -594,16 +655,26 @@ export const registerTeacherForAdmin = async (req, res) => {
console.log(error); console.log(error);
await transaction.rollback(); await transaction.rollback();
if (error.name === "SequelizeUniqueConstraintError") { if (error.name === "SequelizeValidationError") {
const field = error.original.sqlMessage.match(/for key '(.+)'/)[1]; const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
if (field === "teacher_unique_nip") { if (error.name === "SequelizeUniqueConstraintError") {
const tableMatch =
error.original.sqlMessage.match(/for key '(.+)\.(.+)'/);
const tableName = tableMatch ? tableMatch[1] : null;
const constraintName = tableMatch ? tableMatch[2] : null;
if (tableName === "users" && constraintName === "user_unique_email") {
return response(400, null, "Email already registered!", res);
}
if (tableName === "teacher" && constraintName === "teacher_unique_nip") {
return response(400, null, "NIP already registered!", res); return response(400, null, "NIP already registered!", res);
} }
if (field === "user_unique_email") { return response(400, null, "Unique constraint violation!", res);
return response(400, null, "Email already registered!", res);
}
} }
response(500, null, "Internal Server Error", res); response(500, null, "Internal Server Error", res);
@ -667,16 +738,26 @@ export const registerStudentForAdminAndTeacher = async (req, res) => {
await transaction.rollback(); await transaction.rollback();
if (error.name === "SequelizeUniqueConstraintError") { if (error.name === "SequelizeValidationError") {
const field = error.original.sqlMessage.match(/for key '(.+)'/)[1]; const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
if (field === "student_unique_nisn") { if (error.name === "SequelizeUniqueConstraintError") {
const tableMatch =
error.original.sqlMessage.match(/for key '(.+)\.(.+)'/);
const tableName = tableMatch ? tableMatch[1] : null;
const constraintName = tableMatch ? tableMatch[2] : null;
if (tableName === "users" && constraintName === "user_unique_email") {
return response(400, null, "Email already registered!", res);
}
if (tableName === "student" && constraintName === "student_unique_nisn") {
return response(400, null, "NISN already registered!", res); return response(400, null, "NISN already registered!", res);
} }
if (field === "user_unique_email") { return response(400, null, "Unique constraint violation!", res);
return response(400, null, "Email already registered!", res);
}
} }
response(500, null, "Internal Server Error", res); response(500, null, "Internal Server Error", res);
@ -844,6 +925,12 @@ export const registerStudentCSV = async (req, res) => {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
await transaction.rollback(); await transaction.rollback();
if (error.name === "SequelizeValidationError") {
const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
response(500, null, "Internal Server Error", res); response(500, null, "Internal Server Error", res);
} }
}; };
@ -1196,6 +1283,15 @@ export const resetPassword = async (req, res) => {
return response(400, null, "New password is required!", res); return response(400, null, "New password is required!", res);
} }
if (NEW_PASSWORD.length < 8) {
return response(
400,
null,
"Password must be at least 8 characters long!",
res
);
}
if (!CONFIRM_NEW_PASSWORD) { if (!CONFIRM_NEW_PASSWORD) {
return response(400, null, "Confirm new password is required!", res); return response(400, null, "Confirm new password is required!", res);
} }

View File

@ -523,6 +523,32 @@ export const updateUserById = async (req, res) => {
} catch (error) { } catch (error) {
clearFileBuffers({ PICTURE }); clearFileBuffers({ PICTURE });
await transaction.rollback(); await transaction.rollback();
if (error.name === "SequelizeValidationError") {
const validationErrors = error.errors.map((err) => err.message);
return response(400, null, validationErrors.join("; "), res);
}
if (error.name === "SequelizeUniqueConstraintError") {
const tableMatch =
error.original.sqlMessage.match(/for key '(.+)\.(.+)'/);
const tableName = tableMatch ? tableMatch[1] : null;
const constraintName = tableMatch ? tableMatch[2] : null;
if (tableName === "users" && constraintName === "user_unique_email") {
return response(400, null, "Email already registered!", res);
}
if (tableName === "student" && constraintName === "student_unique_nisn") {
return response(400, null, "NISN already registered!", res);
}
if (tableName === "teacher" && constraintName === "teacher_unique_nip") {
return response(400, null, "NIP already registered!", res);
}
return response(400, null, "Unique constraint violation!", res);
}
console.log(error); console.log(error);
return response(500, null, "Internal Server Error", res); return response(500, null, "Internal Server Error", res);
} }
@ -537,6 +563,15 @@ export const updateUserPasswordById = async (req, res) => {
return response(400, null, "All fields must be filled.", res); return response(400, null, "All fields must be filled.", res);
} }
if (PASSWORD.length < 8) {
return response(
400,
null,
"Password must be at least 8 characters long!",
res
);
}
if (PASSWORD !== CONFIRM_PASSWORD) { if (PASSWORD !== CONFIRM_PASSWORD) {
return response( return response(
400, 400,

View File

@ -38,6 +38,12 @@ const StudentModel = (DataTypes) => {
unique: true, unique: true,
validate: { validate: {
notEmpty: true, notEmpty: true,
is10Digits(value) {
const stringValue = value.toString();
if (stringValue.length !== 10) {
throw new Error("NISN must be exactly 10 digits long");
}
},
}, },
}, },
}, },

View File

@ -30,6 +30,12 @@ const TeacherModel = (DataTypes) => {
unique: true, unique: true,
validate: { validate: {
notEmpty: true, notEmpty: true,
is16Digits(value) {
const stringValue = value.toString();
if (stringValue.length !== 16) {
throw new Error("NIP must be exactly 16 digits long");
}
},
}, },
}, },
}, },

View File

@ -20,19 +20,28 @@ const UserModel = (DataTypes) => {
notEmpty: true, notEmpty: true,
}, },
}, },
PASSWORD: {
type: DataTypes.STRING(100),
allowNull: false,
validate: {
notEmpty: true,
len: {
args: [8, 100],
msg: "Password must be at least 8 characters long",
},
},
},
EMAIL: { EMAIL: {
type: DataTypes.STRING(100), type: DataTypes.STRING(100),
allowNull: false, allowNull: false,
unique: true, unique: true,
validate: { validate: {
notEmpty: true, notEmpty: true,
isEmail: true, isEmail: {
msg: "Email must be a valid email address",
},
}, },
}, },
PASSWORD: {
type: DataTypes.STRING(100),
allowNull: false,
},
ROLE: { ROLE: {
type: DataTypes.STRING(100), type: DataTypes.STRING(100),
allowNull: true, allowNull: true,