Download backend/app/exceptions.py from Jessedbrown/schedule-manager: direct link, hf CLI and curl.
- Browser
- Download file 5.7 kB
-
https://huggingface.co/Jessedbrown/schedule-manager/resolve/main/backend/app/exceptions.py
- Command line
-
hf download hf://Jessedbrown/schedule-manager/backend/app/exceptions.py
-
curl -L -o exceptions.py https://huggingface.co/Jessedbrown/schedule-manager/resolve/main/backend/app/exceptions.py
5.7 kB
| from typing import Any, Optional | |
| from datetime import date, time | |
| class AppException(Exception): | |
| status_code: int = 500 | |
| error_code: str = "internal_error" | |
| def __init__( | |
| self, | |
| message: str, | |
| details: Optional[dict[str, Any]] = None, | |
| error_code: Optional[str] = None, | |
| ): | |
| self.message = message | |
| self.details = details or {} | |
| if error_code: | |
| self.error_code = error_code | |
| super().__init__(message) | |
| def to_dict(self) -> dict[str, Any]: | |
| response = { | |
| "error": self.error_code, | |
| "message": self.message, | |
| } | |
| if self.details: | |
| response["details"] = self.details | |
| return response | |
| class ValidationError(AppException): | |
| status_code = 400 | |
| error_code = "validation_error" | |
| def __init__( | |
| self, | |
| message: str, | |
| field: Optional[str] = None, | |
| invalid_values: Optional[list] = None, | |
| **kwargs, | |
| ): | |
| details = {} | |
| if field: | |
| details["field"] = field | |
| if invalid_values: | |
| details["invalid_values"] = invalid_values | |
| super().__init__(message, details=details, **kwargs) | |
| class EntityNotFoundError(ValidationError): | |
| error_code = "entity_not_found" | |
| def __init__( | |
| self, | |
| entity_type: str, | |
| entity_id: Optional[int] = None, | |
| entity_ids: Optional[list[int]] = None, | |
| ): | |
| if entity_ids: | |
| message = f"{entity_type}(s) not found: {sorted(entity_ids)}" | |
| details = {"entity_type": entity_type, "missing_ids": sorted(entity_ids)} | |
| else: | |
| message = f"{entity_type} with ID {entity_id} not found" | |
| details = {"entity_type": entity_type, "id": entity_id} | |
| super().__init__(message, details=details) | |
| class NotFoundError(AppException): | |
| status_code = 404 | |
| error_code = "not_found" | |
| def __init__( | |
| self, | |
| resource_type: str, | |
| resource_id: int, | |
| ): | |
| message = f"{resource_type} with ID {resource_id} not found" | |
| details = {"resource_type": resource_type, "id": resource_id} | |
| super().__init__(message, details=details) | |
| class ConflictError(AppException): | |
| status_code = 409 | |
| error_code = "conflict" | |
| def __init__( | |
| self, | |
| message: str = "Cannot save class due to scheduling conflicts", | |
| conflicts: Optional[list[dict]] = None, | |
| ): | |
| details = {"conflicts": conflicts or []} | |
| super().__init__(message, details=details) | |
| def to_dict(self) -> dict[str, Any]: | |
| return { | |
| "error": self.error_code, | |
| "message": self.message, | |
| "conflicts": self.details.get("conflicts", []), | |
| } | |
| class ServerError(AppException): | |
| status_code = 500 | |
| error_code = "internal_server_error" | |
| def __init__( | |
| self, | |
| message: str = "An unexpected error occurred", | |
| error_id: Optional[str] = None, | |
| original_error: Optional[Exception] = None, | |
| ): | |
| details = {} | |
| if error_id: | |
| details["error_id"] = error_id | |
| self.original_error = original_error | |
| super().__init__(message, details=details) | |
| class RoomConflictError(ConflictError): | |
| def __init__( | |
| self, | |
| room_name: str, | |
| existing_course: str, | |
| existing_time: str, | |
| suggested_rooms: Optional[list[dict]] = None, | |
| ): | |
| conflicts = [{ | |
| "type": "room", | |
| "message": f"Room {room_name} is already booked for {existing_course}", | |
| "suggestion": self._build_suggestion(suggested_rooms), | |
| }] | |
| super().__init__(conflicts=conflicts) | |
| def _build_suggestion(suggested_rooms: Optional[list[dict]]) -> str: | |
| if not suggested_rooms: | |
| return "Try selecting a different room or time slot" | |
| room_names = [r["name"] for r in suggested_rooms[:3]] | |
| return f"Available rooms: {', '.join(room_names)}" | |
| class InstructorConflictError(ConflictError): | |
| def __init__( | |
| self, | |
| instructor_name: str, | |
| existing_course: str, | |
| existing_time: str, | |
| ): | |
| conflicts = [{ | |
| "type": "instructor", | |
| "message": f"Instructor {instructor_name} is already teaching {existing_course}", | |
| "suggestion": "Try selecting a different instructor or time slot", | |
| }] | |
| super().__init__(conflicts=conflicts) | |
| class StudentConflictError(ConflictError): | |
| pass | |
| class CapacityConflictError(ConflictError): | |
| def __init__( | |
| self, | |
| room_name: str, | |
| capacity: int, | |
| student_count: int, | |
| suggested_rooms: Optional[list[dict]] = None, | |
| ): | |
| conflicts = [{ | |
| "type": "capacity", | |
| "message": f"Room {room_name} has capacity {capacity}, but {student_count} students enrolled", | |
| "suggestion": self._build_suggestion(suggested_rooms, student_count), | |
| }] | |
| super().__init__(conflicts=conflicts) | |
| def _build_suggestion(suggested_rooms: Optional[list[dict]], student_count: int) -> str: | |
| if not suggested_rooms: | |
| return f"Select a room with capacity >= {student_count} or reduce enrollment" | |
| suitable = [r for r in suggested_rooms if r.get("capacity", 0) >= student_count] | |
| if suitable: | |
| room_names = [f"{r['name']} (cap: {r['capacity']})" for r in suitable[:3]] | |
| return f"Rooms with sufficient capacity: {', '.join(room_names)}" | |
| return f"No available rooms with capacity >= {student_count}. Reduce enrollment." | |