From 9fd0caad19040a0681e136f3c575663c140d30af Mon Sep 17 00:00:00 2001 From: akhdanre Date: Tue, 27 May 2025 16:02:14 +0700 Subject: [PATCH] feat: adding exception and and logger handler --- app/controllers/socket_conroller.py | 358 +++++++++++++++------------- 1 file changed, 194 insertions(+), 164 deletions(-) diff --git a/app/controllers/socket_conroller.py b/app/controllers/socket_conroller.py index 4e614de..2f50128 100644 --- a/app/controllers/socket_conroller.py +++ b/app/controllers/socket_conroller.py @@ -17,189 +17,215 @@ class SocketController: def _register_events(self): @self.socketio.on("connect") def on_connect(): - # print(f"Client connected: {request.sid}") - current_app.logger.info(f"Client connected: {request.sid}") - emit("connection_response", {"status": "connected", "sid": request.sid}) + try: + current_app.logger.info(f"Client connected: {request.sid}") + emit("connection_response", {"status": "connected", "sid": request.sid}) + except Exception as e: + emit("error", {"message": f"Connect error: {str(e)}"}) + current_app.logger.error(f"Connect error: {str(e)}") @self.socketio.on("disconnect") def on_disconnect(): - current_app.logger.info(f"Client connected: {request.sid}") - # print(f"Client disconnected: {request.sid}") - pass + try: + current_app.logger.info(f"Client disconnected: {request.sid}") + except Exception as e: + emit("error", {"message": f"Disconnect error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}") @self.socketio.on("join_room") def handle_join_room(data): - session_code = data.get("session_code") - user_id = data.get("user_id") + try: + session_code = data.get("session_code") + user_id = data.get("user_id") - if not session_code or not user_id: - emit("error", {"message": "session_code and user_id are required"}) - return + if not session_code or not user_id: + emit("error", {"message": "session_code and user_id are required"}) + return - session = self.session_service.join_session( - session_code=session_code, - user_id=user_id, - ) + session = self.session_service.join_session(session_code, user_id) + if session is None: + emit( + "error", + {"message": "Failed to join session or session inactive"}, + ) + return - if session is None: - emit("error", {"message": "Failed to join session or session inactive"}) - return + session_id = session["session_id"] + join_room(session_id) - session_id = session["session_id"] + message = ( + "Admin has joined the room." + if session["is_admin"] + else f"User {session['username']} has joined the room." + ) - join_room(session_id) - - if session["is_admin"]: - message = "Admin has joined the room." - else: - message = f"User {session['username']} has joined the room." - - current_app.logger.info(f"Client joined: {message}") - emit( - "room_message", - { - "type": "join", - "message": message, - "room": session_id, - "argument": "adm_update", - "data": { - "session_info": session["session_info"], - "quiz_info": session["quiz_info"], - }, - }, - to=request.sid, - ) - - emit( - "room_message", - { - "type": "participan_join", - "message": message, - "room": session_id, - "argument": "adm_update", - "data": { - "participants": session["session_info"]["participants"], - }, - }, - room=session_id, - skip_sid=request.sid, - ) - - @self.socketio.on("leave_room") - def handle_leave_room(data): - session_id = data.get("session_id") - user_id = data.get("user_id") - username = data.get("username", "anonymous") - - leave_result = self.session_service.leave_session( - session_id=session_id, - user_id=user_id, - ) - leave_room(session_id) - if leave_result["is_success"]: + current_app.logger.info(f"Client joined: {message}") emit( "room_message", { - "type": "participan_leave", - "message": f"{username} has left the room.", + "type": "join", + "message": message, "room": session_id, "argument": "adm_update", "data": { - "participants": leave_result["participants"], + "session_info": session["session_info"], + "quiz_info": session["quiz_info"], + }, + }, + to=request.sid, + ) + + emit( + "room_message", + { + "type": "participan_join", + "message": message, + "room": session_id, + "argument": "adm_update", + "data": { + "participants": session["session_info"]["participants"], }, }, room=session_id, skip_sid=request.sid, ) - emit( - "room_message", - { - "type": "leave", - "message": f"{username} has left the room.", - "room": session_id, - "argument": "adm_update", - "data": None, - }, - room=session_id, - to=request.sid, - ) + + except Exception as e: + emit("error", {"message": f"Join room error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}") + + @self.socketio.on("leave_room") + def handle_leave_room(data): + try: + session_id = data.get("session_id") + user_id = data.get("user_id") + username = data.get("username", "anonymous") + + leave_result = self.session_service.leave_session(session_id, user_id) + leave_room(session_id) + + if leave_result["is_success"]: + emit( + "room_message", + { + "type": "participan_leave", + "message": f"{username} has left the room.", + "room": session_id, + "argument": "adm_update", + "data": { + "participants": leave_result["participants"], + }, + }, + room=session_id, + skip_sid=request.sid, + ) + + emit( + "room_message", + { + "type": "leave", + "message": f"{username} has left the room.", + "room": session_id, + "argument": "adm_update", + "data": None, + }, + room=session_id, + to=request.sid, + ) + + except Exception as e: + emit("error", {"message": f"Leave room error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}") @self.socketio.on("send_message") def on_send_message(data): - session_code = data.get("session_id") - message = data.get("message") - username = data.get("username", "anonymous") - emit( - "receive_message", - {"message": message, "from": username}, - room=session_code, - ) + try: + session_code = data.get("session_id") + message = data.get("message") + username = data.get("username", "anonymous") + + emit( + "receive_message", + {"message": message, "from": username}, + room=session_code, + ) + except Exception as e: + emit("error", {"message": f"Send message error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}") @self.socketio.on("end_session") def handle_end_session(data): - session_code = data.get("session_id") - user_id = data.get("user_id") - if not session_code or not user_id: - emit("error", {"message": "session_id and user_id required"}) - return + try: + session_code = data.get("session_id") + user_id = data.get("user_id") + if not session_code or not user_id: + emit("error", {"message": "session_id and user_id required"}) + return - # Validasi user berhak mengakhiri session - self.session_service.end_session(session_id=session_code, user_id=user_id) + self.session_service.end_session( + session_id=session_code, user_id=user_id + ) - # Bersihkan semua data session di Redis - for key in [ - self._answers_key(session_code), - self._scores_key(session_code), - self._questions_key(session_code), - ]: - self.redis_repo.delete_key(key) + for key in [ + self._answers_key(session_code), + self._scores_key(session_code), + self._questions_key(session_code), + ]: + self.redis_repo.delete_key(key) - emit( - "room_closed", - {"message": "Session has ended.", "room": session_code}, - room=session_code, - ) + emit( + "room_closed", + {"message": "Session has ended.", "room": session_code}, + room=session_code, + ) + except Exception as e: + emit("error", {"message": f"End session error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}") @self.socketio.on("start_quiz") def handle_start_quiz(data): - session_id = data.get("session_id") - if not session_id: - emit("error", {"message": "session_id is required"}) - return + try: + session_id = data.get("session_id") + if not session_id: + emit("error", {"message": "session_id is required"}) + return - emit("quiz_started", {"message": "Quiz has started!"}, room=session_id) - threading.Thread( - target=self.session_service.run_quiz_flow, - args=(session_id, self.socketio), - daemon=True, - ).start() + emit("quiz_started", {"message": "Quiz has started!"}, room=session_id) + threading.Thread( + target=self.session_service.run_quiz_flow, + args=(session_id, self.socketio), + daemon=True, + ).start() + except Exception as e: + emit("error", {"message": f"Start quiz error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}") @self.socketio.on("submit_answer") def handle_submit_answer(data): - session_id = data.get("session_id") - user_id = data.get("user_id") - question_index = data.get("question_index") - user_answer = data.get("answer") - time_spent = data.get("time_spent") - - if not all( - [ - session_id, - user_id, - question_index is not None, - user_answer is not None, - time_spent is not None, - ] - ): - emit( - "error", - { - "message": "session_id, user_id, question_index, and answer are required" - }, - ) - return - try: + session_id = data.get("session_id") + user_id = data.get("user_id") + question_index = data.get("question_index") + user_answer = data.get("answer") + time_spent = data.get("time_spent") + + if not all( + [ + session_id, + user_id, + question_index is not None, + user_answer is not None, + time_spent is not None, + ] + ): + emit( + "error", + { + "message": "session_id, user_id, question_index, and answer are required" + }, + ) + return + result = self.session_service.submit_answer( session_id=session_id, user_id=user_id, @@ -207,25 +233,29 @@ class SocketController: answer=user_answer, time_spent=time_spent, ) + + emit( + "answer_submitted", + { + "question_index": result["question_index"], + "answer": result["answer"], + "correct": result["correct"], + "score": result["scores"], + }, + to=request.sid, + ) + + emit( + "score_update", + { + "scores": self.session_service.get_ranked_scores(session_id), + }, + room=session_id, + ) + except ValueError as exc: emit("error", {"message": str(exc)}) - return - - emit( - "answer_submitted", - { - "question_index": result["question_index"], - "answer": result["answer"], - "correct": result["correct"], - "score": result["scores"], - }, - to=request.sid, - ) - - emit( - "score_update", - { - "scores": self.session_service.get_ranked_scores(session_id), - }, - room=session_id, - ) + current_app.logger.error(f"error: {str(exc)}") + except Exception as e: + emit("error", {"message": f"Submit answer error: {str(e)}"}) + current_app.logger.error(f"error: {str(e)}")