mirror of
https://github.com/ets-cfuhrman-pfe/EvalueTonSavoir.git
synced 2025-08-11 21:23:54 -04:00
traitement des erreurs et afficher un dialogue erreur si room existe
This commit is contained in:
parent
d584374347
commit
a99664d8ff
7 changed files with 157 additions and 88 deletions
|
|
@ -27,7 +27,8 @@ import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
NativeSelect,
|
NativeSelect,
|
||||||
CardContent,
|
CardContent,
|
||||||
styled
|
styled,
|
||||||
|
DialogContentText
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import {
|
import {
|
||||||
Search,
|
Search,
|
||||||
|
|
@ -62,6 +63,8 @@ const Dashboard: React.FC = () => {
|
||||||
const [openAddRoomDialog, setOpenAddRoomDialog] = useState(false);
|
const [openAddRoomDialog, setOpenAddRoomDialog] = useState(false);
|
||||||
const [newRoomTitle, setNewRoomTitle] = useState('');
|
const [newRoomTitle, setNewRoomTitle] = useState('');
|
||||||
const { selectedRoom, selectRoom, createRoom } = useRooms();
|
const { selectedRoom, selectRoom, createRoom } = useRooms();
|
||||||
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
const [showErrorDialog, setShowErrorDialog] = useState(false);
|
||||||
|
|
||||||
// Filter quizzes based on search term
|
// Filter quizzes based on search term
|
||||||
// const filteredQuizzes = quizzes.filter(quiz =>
|
// const filteredQuizzes = quizzes.filter(quiz =>
|
||||||
|
|
@ -105,21 +108,25 @@ const Dashboard: React.FC = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSelectRoom = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const handleSelectRoom = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
if (event.target.value === "add-room") {
|
if (event.target.value === 'add-room') {
|
||||||
setOpenAddRoomDialog(true);
|
setOpenAddRoomDialog(true);
|
||||||
} else {
|
} else {
|
||||||
selectRoom(event.target.value);
|
selectRoom(event.target.value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmitCreateRoom = async () => {
|
const handleSubmitCreateRoom = async () => {
|
||||||
if (newRoomTitle.trim()) {
|
if (newRoomTitle.trim()) {
|
||||||
await createRoom(newRoomTitle);
|
try {
|
||||||
// reload the list of rooms
|
await createRoom(newRoomTitle);
|
||||||
const userRooms = await ApiService.getUserRooms();
|
const userRooms = await ApiService.getUserRooms();
|
||||||
setRooms(userRooms as RoomType[]);
|
setRooms(userRooms as RoomType[]);
|
||||||
setOpenAddRoomDialog(false);
|
setOpenAddRoomDialog(false);
|
||||||
setNewRoomTitle('');
|
setNewRoomTitle('');
|
||||||
|
} catch (error) {
|
||||||
|
setErrorMessage(error instanceof Error ? error.message : "Erreur inconnue");
|
||||||
|
setShowErrorDialog(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -391,10 +398,7 @@ const Dashboard: React.FC = () => {
|
||||||
|
|
||||||
<div className="roomSelection">
|
<div className="roomSelection">
|
||||||
<label htmlFor="select-room">Sélectionner une salle: </label>
|
<label htmlFor="select-room">Sélectionner une salle: </label>
|
||||||
<select
|
<select value={selectedRoom?._id || ''} onChange={(e) => handleSelectRoom(e)}>
|
||||||
value={selectedRoom?._id || ''}
|
|
||||||
onChange={(e) => handleSelectRoom(e)}
|
|
||||||
>
|
|
||||||
{/* <option value="">Sélectionner une salle</option> */}
|
{/* <option value="">Sélectionner une salle</option> */}
|
||||||
{rooms.map((room) => (
|
{rooms.map((room) => (
|
||||||
<option key={room._id} value={room._id}>
|
<option key={room._id} value={room._id}>
|
||||||
|
|
@ -426,6 +430,15 @@ const Dashboard: React.FC = () => {
|
||||||
<Button onClick={handleSubmitCreateRoom}>Créer</Button>
|
<Button onClick={handleSubmitCreateRoom}>Créer</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
<Dialog open={showErrorDialog} onClose={() => setShowErrorDialog(false)}>
|
||||||
|
<DialogTitle>Erreur</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogContentText>{errorMessage}</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setShowErrorDialog(false)}>Fermer</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
<div className="search-bar">
|
<div className="search-bar">
|
||||||
<TextField
|
<TextField
|
||||||
|
|
|
||||||
|
|
@ -482,31 +482,34 @@ class ApiService {
|
||||||
return `Une erreur inattendue s'est produite.`;
|
return `Une erreur inattendue s'est produite.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async createRoom(title: string): Promise<string | string> {
|
public async createRoom(title: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
if (!title) {
|
if (!title) {
|
||||||
throw new Error(`Le titre de la salle est requis.`);
|
throw new Error("Le titre de la salle est requis.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const url: string = this.constructRequestUrl(`/room/create`);
|
const url: string = this.constructRequestUrl(`/room/create`);
|
||||||
const headers = this.constructRequestHeaders();
|
const headers = this.constructRequestHeaders();
|
||||||
const body = { title };
|
const body = { title };
|
||||||
|
|
||||||
const result: AxiosResponse = await axios.post(url, body, { headers });
|
const result = await axios.post<{ roomId: string }>(url, body, { headers });
|
||||||
|
|
||||||
if (result.status !== 200) {
|
|
||||||
throw new Error(`La création de la salle a échoué. Status: ${result.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return `Salle créée avec succès. ID de la salle: ${result.data.roomId}`;
|
return `Salle créée avec succès. ID de la salle: ${result.data.roomId}`;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error details: ", error);
|
|
||||||
if (axios.isAxiosError(error)) {
|
if (axios.isAxiosError(error)) {
|
||||||
const err = error as AxiosError;
|
const err = error as AxiosError;
|
||||||
const data = err.response?.data as { error: string } | undefined;
|
|
||||||
return data?.error || 'Erreur serveur inconnue lors de la création de la salle.';
|
const serverMessage = (err.response?.data as { message?: string })?.message
|
||||||
|
|| (err.response?.data as { error?: string })?.error
|
||||||
|
|| err.message;
|
||||||
|
|
||||||
|
if (err.response?.status === 409) {
|
||||||
|
throw new Error(serverMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(serverMessage || "Erreur serveur inconnue");
|
||||||
}
|
}
|
||||||
return `Une erreur inattendue s'est produite.`;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
class AppError extends Error {
|
class AppError extends Error {
|
||||||
constructor(message, statusCode) {
|
constructor(message, statusCode) {
|
||||||
super(message);
|
super(message);
|
||||||
this.statusCode = statusCode;
|
this.statusCode = statusCode || 500;
|
||||||
|
|
||||||
|
Object.setPrototypeOf(this, new.target.prototype);
|
||||||
|
|
||||||
|
Error.captureStackTrace(this, this.constructor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AppError;
|
module.exports = AppError;
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,38 @@ exports.COPY_FOLDER_ERROR = {
|
||||||
message: 'Une erreur s\'est produite lors de la copie du dossier.',
|
message: 'Une erreur s\'est produite lors de la copie du dossier.',
|
||||||
code: 400
|
code: 400
|
||||||
}
|
}
|
||||||
|
exports.ROOM_NOT_FOUND = {
|
||||||
|
message: 'Aucune salle portant cet identifiant n\'a été trouvé.',
|
||||||
|
code: 404
|
||||||
|
}
|
||||||
|
exports.ROOM_ALREADY_EXISTS = {
|
||||||
|
message: 'Une salle avec ce nom existe déjà',
|
||||||
|
code: 409
|
||||||
|
};
|
||||||
|
exports.UPDATE_ROOM_ERROR = {
|
||||||
|
message: 'Une erreur s\'est produite lors de la mise à jour de la salle.',
|
||||||
|
code: 400
|
||||||
|
}
|
||||||
|
exports.DELETE_ROOM_ERROR = {
|
||||||
|
message: 'Une erreur s\'est produite lors de la suppression de la salle.',
|
||||||
|
code: 400
|
||||||
|
}
|
||||||
|
exports.GETTING_ROOM_ERROR = {
|
||||||
|
message: 'Une erreur s\'est produite lors de la récupération de la salle.',
|
||||||
|
code: 400
|
||||||
|
}
|
||||||
|
exports.MOVING_ROOM_ERROR = {
|
||||||
|
message: 'Une erreur s\'est produite lors du déplacement de la salle.',
|
||||||
|
code: 400
|
||||||
|
}
|
||||||
|
exports.DUPLICATE_ROOM_ERROR = {
|
||||||
|
message: 'Une erreur s\'est produite lors de la duplication de la salle.',
|
||||||
|
code: 400
|
||||||
|
}
|
||||||
|
exports.COPY_ROOM_ERROR = {
|
||||||
|
message: 'Une erreur s\'est produite lors de la copie de la salle.',
|
||||||
|
code: 400
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,11 @@ class RoomsController {
|
||||||
|
|
||||||
create = async (req, res, next) => {
|
create = async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const { title } = req.body;
|
if (!req.user || !req.user.userId) {
|
||||||
|
throw new AppError("Utilisateur non authentifié", 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = req.body;
|
||||||
if (!title) {
|
if (!title) {
|
||||||
throw new AppError(MISSING_REQUIRED_PARAMETER);
|
throw new AppError(MISSING_REQUIRED_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
@ -26,18 +29,21 @@ class RoomsController {
|
||||||
|
|
||||||
const roomExists = await this.rooms.roomExists(normalizedTitle);
|
const roomExists = await this.rooms.roomExists(normalizedTitle);
|
||||||
|
|
||||||
|
|
||||||
if (roomExists) {
|
if (roomExists) {
|
||||||
throw new AppError(ROOM_ALREADY_EXISTS);
|
const error = new AppError(ROOM_ALREADY_EXISTS);
|
||||||
|
error.message = "Cette salle existe déjà";
|
||||||
|
error.statusCode = 409;
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.rooms.create(normalizedTitle, req.user.userId);
|
const result = await this.rooms.create(normalizedTitle, req.user.userId);
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(201).json({
|
||||||
message: "Room cree avec succes.",
|
message: "Room créée avec succès.",
|
||||||
roomId: result.insertedId,
|
roomId: result.insertedId,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return next(error);
|
next(Object.assign(error, { message: error.message }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -194,13 +200,9 @@ class RoomsController {
|
||||||
if (!title) {
|
if (!title) {
|
||||||
throw new AppError(MISSING_REQUIRED_PARAMETER);
|
throw new AppError(MISSING_REQUIRED_PARAMETER);
|
||||||
}
|
}
|
||||||
|
const exists = await this.rooms.roomExists(title);
|
||||||
const normalizedTitle = title.toLowerCase();
|
|
||||||
|
|
||||||
const exists = await this.rooms.roomExists(normalizedTitle);
|
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
message: `La salle avec le titre "${title}" existe déjà.`,
|
|
||||||
exists: exists,
|
exists: exists,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,28 @@ const AppError = require("./AppError");
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
const errorHandler = (error, req, res, _next) => {
|
const errorHandler = (error, req, res, _next) => {
|
||||||
|
res.setHeader('Cache-Control', 'no-store');
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
console.log("Erreur reçue :", {
|
||||||
|
message: error.message,
|
||||||
|
stack: error.stack,
|
||||||
|
constructor: error.constructor.name,
|
||||||
|
proto: Object.getPrototypeOf(error)
|
||||||
|
});
|
||||||
|
|
||||||
if (error instanceof AppError) {
|
if (error instanceof AppError) {
|
||||||
logError(error);
|
return res.status(error.statusCode).json({
|
||||||
return res.status(error.statusCode).json({
|
message: error.message,
|
||||||
error: error.message
|
code: error.statusCode
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logError(error.stack);
|
return res.status(500).json({
|
||||||
return res.status(505).send("Oups! We screwed up big time. ┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻");
|
message: "Erreur technique",
|
||||||
}
|
code: 500
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const logError = (error) => {
|
const logError = (error) => {
|
||||||
const time = new Date();
|
const time = new Date();
|
||||||
|
|
|
||||||
|
|
@ -6,34 +6,38 @@ class Rooms {
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(title, userId) {
|
async create(title, userId) {
|
||||||
|
try {
|
||||||
if (!title || !userId) {
|
if (!title || !userId) {
|
||||||
throw new Error('Missing required parameter(s)');
|
throw new AppError('Missing required parameter(s)', 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.db.connect();
|
||||||
|
const conn = this.db.getConnection();
|
||||||
|
const roomsCollection = conn.collection('rooms');
|
||||||
|
const normalizedTitle = title.toLowerCase();
|
||||||
|
|
||||||
|
const existingRoom = await roomsCollection.findOne({ title: normalizedTitle, userId: userId });
|
||||||
|
|
||||||
|
if (existingRoom) {
|
||||||
|
throw new AppError('Une salle avec ce nom existe déjà', 409);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newRoom = {
|
||||||
|
userId: userId,
|
||||||
|
title: title,
|
||||||
|
created_at: new Date()
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await roomsCollection.insertOne(newRoom);
|
||||||
|
|
||||||
|
return result.insertedId;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in create function:", error);
|
||||||
|
throw new AppError(error.message || "Internal Server Error", 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.db.connect()
|
|
||||||
const conn = this.db.getConnection();
|
|
||||||
|
|
||||||
const roomsCollection = conn.collection('rooms');
|
|
||||||
|
|
||||||
const normalizedTitle = title.toLowerCase();
|
|
||||||
|
|
||||||
const existingRoom = await roomsCollection.findOne({ title: normalizedTitle, userId: userId });
|
|
||||||
|
|
||||||
if (existingRoom) {
|
|
||||||
throw new Error('Room already exists');
|
|
||||||
}
|
|
||||||
|
|
||||||
const newRoom = {
|
|
||||||
userId: userId,
|
|
||||||
title: title,
|
|
||||||
created_at: new Date()
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await roomsCollection.insertOne(newRoom);
|
|
||||||
|
|
||||||
return result.insertedId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getUserRooms(userId) {
|
async getUserRooms(userId) {
|
||||||
await this.db.connect()
|
await this.db.connect()
|
||||||
|
|
@ -101,16 +105,20 @@ class Rooms {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
async roomExists(title) {
|
async roomExists(title) { // Ajouter userId en paramètre
|
||||||
await this.db.connect();
|
try {
|
||||||
const conn = this.db.getConnection();
|
await this.db.connect();
|
||||||
|
const conn = this.db.getConnection();
|
||||||
const roomsCollection = conn.collection('rooms');
|
const existingRoom = await conn.collection('rooms').findOne({
|
||||||
const normalizedTitle = title.toLowerCase();
|
title: title.toLowerCase()
|
||||||
const existingRoom = await roomsCollection.findOne({ title: normalizedTitle });
|
});
|
||||||
return existingRoom ? true : false;
|
return !!existingRoom;
|
||||||
|
} catch (error) {
|
||||||
|
throw new AppError("Erreur base de données", 500); // Encapsuler les erreurs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getRoomById(roomId) {
|
async getRoomById(roomId) {
|
||||||
await this.db.connect();
|
await this.db.connect();
|
||||||
const conn = this.db.getConnection();
|
const conn = this.db.getConnection();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue