Global Error Handling
Relevant source files
The following files were used as context for generating this wiki page:
- src/main/java/com/example/demo/exception/GlobalExceptionHandler.java
- src/main/java/com/example/demo/exception/AccessDeniedException.java
- src/main/java/com/example/demo/exception/ResourceNotFoundException.java
- src/main/resources/static/js/api.js
- README.md
- src/main/java/com/example/demo/services/TaskService.java
- src/main/java/com/example/demo/services/AttachmentService.java
The Global Error Handling system in the Dashboard Task Management (DTM) project provides a centralized mechanism for capturing, processing, and responding to exceptions across the application. By utilizing Spring Boot's @RestControllerAdvice, the system ensures that both functional and security-related errors are transformed into consistent, machine-readable JSON responses for the frontend.
This architecture decouples error logic from business services, allowing components like TaskService or AttachmentService to throw specific exceptions (e.g., ResourceNotFoundException) while the GlobalExceptionHandler manages the HTTP status codes and error messaging delivered to the client.
Sources: GlobalExceptionHandler.java:1-12, README.md:158-166
Backend Exception Architecture
The backend utilizes a specialized handler class to intercept exceptions thrown during API execution. This ensures that the client receives a structured response even when unexpected failures occur.
Exception Types and Mapping
The system categorizes errors into specific HTTP status codes based on the exception type:
| Exception Class | HTTP Status | Description |
|---|---|---|
ResourceNotFoundException | 404 Not Found | Thrown when an entity (Task, User, Project) is missing. |
AccessDeniedException | 403 Forbidden | Thrown when a user lacks permission for a specific action. |
MethodArgumentNotValidException | 400 Bad Request | Triggered during JSR-303 validation failures on request bodies. |
IllegalArgumentException | 400 Bad Request | Often thrown in services for invalid business logic (e.g., past due dates). |
Exception (General) | 500 Internal Error | Catch-all for unhandled runtime exceptions. |
Sources: GlobalExceptionHandler.java:14-41, TaskService.java:237-245, AttachmentService.java:55-57
Error Flow Logic
The following diagram illustrates how an exception propagates from the service layer through the global handler to the client.
The GlobalExceptionHandler uses the @ExceptionHandler annotation to trap specific classes. For validation errors (MethodArgumentNotValidException), it iterates through FieldError objects to build a map of field names and their corresponding error messages.
Sources: GlobalExceptionHandler.java:26-33, src/main/java/com/example/demo/exception/GlobalExceptionHandler.java:14-25
Frontend Error Interception
The frontend communicates with the backend via a centralized API module in api.js. This module implements standardized error handling for all asynchronous requests.
Centralized Fetch Handling
The request function in api.js evaluates the response status of every fetch call. If a response is not "ok", it attempts to parse the JSON error body returned by the GlobalExceptionHandler.
// src/main/resources/static/js/api.js lines 22-26
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.error || 'Ошибка сервера');
}
Specialized 401 Unauthorized Handling
The frontend specifically monitors for 401 Unauthorized status codes, which indicate an expired or missing JWT token. When encountered, the system clears the local dtm_token and redirects the user to the login page.
Sources: api.js:18-21, README.md:144-156
Service-Level Validation and Security
The global error handling system relies on services to enforce business rules and security constraints by throwing the appropriate exceptions.
Data Integrity and Validation
In TaskService.java, the validateCreateRequest method ensures that mandatory fields (Project ID, Title, Due Date, Assignees) are present and valid before processing. If these conditions are not met, an IllegalArgumentException is thrown, which results in a 400 Bad Request via the catch-all handler.
Sources: TaskService.java:319-330, GlobalExceptionHandler.java:36-40
Role-Based Access Control (RBAC) Errors
The AttachmentService and TaskService perform manual scope checks. For instance, the TEAM role is restricted from attaching files to anything other than comments.
// src/main/java/com/example/demo/services/AttachmentService.java lines 104-106
if (user.getRole() == Role.TEAM && entityType != EntityType.COMMENT) {
throw new AccessDeniedException("Команда может прикреплять файлы только к комментариям");
}
Citations: AttachmentService.java:104-106, TaskService.java:297-317
Conclusion
Global Error Handling in the DTM project is a multi-layered system that bridges backend Java exceptions with frontend JavaScript error handling. By centralizing the logic in GlobalExceptionHandler.java and api.js, the project ensures that users receive descriptive feedback for validation failures, missing resources, and unauthorized access attempts while maintaining a clean separation of concerns within the service architecture.