diff --git a/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java b/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java index 06ac2e3..7c645f5 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/business/TaskService.java @@ -5,11 +5,12 @@ import com.javanauta.ts.taskscheduler.business.mapper.TaskUpdateConverter; import com.javanauta.ts.taskscheduler.infrastructure.entity.Task; import com.javanauta.ts.taskscheduler.infrastructure.enums.NotificationStatusEnum; -import com.javanauta.ts.taskscheduler.infrastructure.exception.InvalidTimeZoneException; +import com.javanauta.ts.taskscheduler.infrastructure.exception.ValidationErrorException; import com.javanauta.ts.taskscheduler.infrastructure.exception.ResourceNotFoundException; import com.javanauta.ts.taskscheduler.infrastructure.repository.TaskRepository; import com.javanauta.ts.taskscheduler.infrastructure.security.JwtUtil; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.time.Instant; @@ -18,6 +19,7 @@ @Service @RequiredArgsConstructor +@Slf4j public class TaskService { private final TaskRepository taskRepository; @@ -31,14 +33,15 @@ public TaskDTO saveTask(String token, TaskDTO taskDTO) { taskDTO.setNotificationStatusEnum(NotificationStatusEnum.PENDING); validateTimeZoneId(taskDTO.getTimeZoneId()); - Task task = taskConverter.toTask(taskDTO); + Task savedTask = taskRepository.save(taskConverter.toTask(taskDTO)); + log.info("Task {} created", savedTask.getId()); - return taskConverter.toTaskDTO(taskRepository.save(task)); + return taskConverter.toTaskDTO(savedTask); } private void validateTimeZoneId(String timeZoneId) { if (!ZoneId.getAvailableZoneIds().contains(timeZoneId)) { - throw new InvalidTimeZoneException("Invalid time zone ID: " + timeZoneId); + throw new ValidationErrorException("Invalid time zone ID"); } } @@ -47,32 +50,40 @@ public List findTaskByTimePeriod(Instant initialDateTime, Instant final } public List findTaskByUserEmail(String token) { + // Assumes the user exists as it's being extracted from the token return taskConverter.toTaskDTOList(taskRepository.findByUserEmail(jwtUtil.extractUsername(token.substring(7)))); } public void deleteTaskById(String id) { if (taskRepository.existsById(id)) { taskRepository.deleteById(id); + log.info("Task {} deleted", id); } else { - throw new ResourceNotFoundException(String.format("Task with ID '%s' not found.", id)); + throw new ResourceNotFoundException("Task not found"); } } public TaskDTO modifyTaskStatusById (NotificationStatusEnum notificationStatusEnum, String id) { - Task task = taskRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(String.format("Task with ID '%s' not found.", id))); + Task task = taskRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Task not found")); task.setNotificationStatusEnum(notificationStatusEnum); task.setModificationDateTime(Instant.now()); - return taskConverter.toTaskDTO(taskRepository.save(task)); + Task updatedTask = taskRepository.save(task); + log.info("Status of task {} updated", updatedTask.getId()); + + return taskConverter.toTaskDTO(updatedTask); } public TaskDTO updateTaskById (TaskDTO taskDTO, String id) { - Task task = taskRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(String.format("Task with ID '%s' not found.", id))); + Task task = taskRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Task not found")); taskUpdateConverter.updateTasks(taskDTO, task); validateTimeZoneId(task.getTimeZoneId()); task.setModificationDateTime(Instant.now()); - return taskConverter.toTaskDTO(taskRepository.save(task)); + Task updatedTask = taskRepository.save(task); + log.info("Task {} updated", updatedTask.getId()); + + return taskConverter.toTaskDTO(updatedTask); } } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java b/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java index 9d8693a..286d287 100644 --- a/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java +++ b/src/main/java/com/javanauta/ts/taskscheduler/controller/GlobalExceptionHandler.java @@ -1,28 +1,36 @@ package com.javanauta.ts.taskscheduler.controller; -import com.javanauta.ts.taskscheduler.infrastructure.exception.InvalidTimeZoneException; +import com.javanauta.ts.taskscheduler.infrastructure.exception.ValidationErrorException; import com.javanauta.ts.taskscheduler.infrastructure.exception.ResourceNotFoundException; -import com.javanauta.ts.taskscheduler.infrastructure.exception.UnauthorizedException; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice +@Slf4j public class GlobalExceptionHandler { + // business exceptions + @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity handlerResourceNotFoundException(ResourceNotFoundException ex) { - return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND); + log.warn("Resource not found exception: {}", ex.getMessage()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } - @ExceptionHandler(UnauthorizedException.class) - public ResponseEntity handlerUnauthorizedException(UnauthorizedException ex) { - return new ResponseEntity<>(ex.getMessage(), HttpStatus.UNAUTHORIZED); + @ExceptionHandler(ValidationErrorException.class) + public ResponseEntity handlerValidationErrorException(ValidationErrorException ex) { + log.warn("Invalid value exception: {}", ex.getMessage()); + return ResponseEntity.status(HttpStatus.UNPROCESSABLE_CONTENT).body(ex.getMessage()); } - @ExceptionHandler(InvalidTimeZoneException.class) - public ResponseEntity handlerInvalidTimeZoneId(InvalidTimeZoneException ex) { - return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); + // Generic error handling + + @ExceptionHandler(Exception.class) + public ResponseEntity handleGenericException(Exception ex) { + log.error("Unhandled exception", ex); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal server error"); } } diff --git a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/InvalidTimeZoneException.java b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/InvalidTimeZoneException.java deleted file mode 100644 index 067eab1..0000000 --- a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/InvalidTimeZoneException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.javanauta.ts.taskscheduler.infrastructure.exception; - -public class InvalidTimeZoneException extends RuntimeException { - public InvalidTimeZoneException(String message) { - super(message); - } - public InvalidTimeZoneException(String message, Throwable throwable) { - super(message, throwable); - } -} diff --git a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/UnauthorizedException.java b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/UnauthorizedException.java deleted file mode 100644 index 1cd3323..0000000 --- a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/UnauthorizedException.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.javanauta.ts.taskscheduler.infrastructure.exception; - -import org.springframework.security.core.AuthenticationException; - -public class UnauthorizedException extends AuthenticationException { - public UnauthorizedException(String message) { - super(message); - } - - public UnauthorizedException(String message, Throwable throwable) { - super(message, throwable); - } -} diff --git a/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/ValidationErrorException.java b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/ValidationErrorException.java new file mode 100644 index 0000000..9a9ab39 --- /dev/null +++ b/src/main/java/com/javanauta/ts/taskscheduler/infrastructure/exception/ValidationErrorException.java @@ -0,0 +1,10 @@ +package com.javanauta.ts.taskscheduler.infrastructure.exception; + +public class ValidationErrorException extends RuntimeException { + public ValidationErrorException(String message) { + super(message); + } + public ValidationErrorException(String message, Throwable throwable) { + super(message, throwable); + } +}