Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Exception Handling for Invalid Sort Fields #56

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/main/java/com/libraryman_api/book/BookService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.stereotype.Service;

import com.libraryman_api.exception.InvalidSortFieldException;
import com.libraryman_api.exception.ResourceNotFoundException;

/**
Expand Down Expand Up @@ -42,9 +44,14 @@ public BookService(BookRepository bookRepository) {
*
* @param pageable the pagination information, including the page number and size
* @return a {@link Page} of {@link Book} representing all books
* @throws InvalidSortFieldException if an invalid sortBy field is specified
*/
public Page<Book> getAllBooks(Pageable pageable) {
return bookRepository.findAll(pageable);
try {
return bookRepository.findAll(pageable);
} catch (PropertyReferenceException ex) {
throw new InvalidSortFieldException("The specified 'sortBy' value is invalid.");
}
}

/**
Expand Down
26 changes: 19 additions & 7 deletions src/main/java/com/libraryman_api/borrowing/BorrowingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.libraryman_api.book.BookService;
import com.libraryman_api.book.Book;
import com.libraryman_api.fine.Fines;
import com.libraryman_api.exception.InvalidSortFieldException;
import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.fine.FineRepository;
import com.libraryman_api.member.MemberService;
Expand All @@ -11,6 +12,7 @@

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
Expand Down Expand Up @@ -66,9 +68,14 @@ public BorrowingService(BorrowingRepository borrowingRepository, FineRepository
*
* @param pageable the pagination information, including the page number and size
* @return a {@link Page} of {@link Borrowings} representing all borrowings
* @throws InvalidSortFieldException if an invalid sortBy field is specified
*/
public Page<Borrowings> getAllBorrowings(Pageable pageable) {
return borrowingRepository.findAll(pageable);
try {
return borrowingRepository.findAll(pageable);
} catch (PropertyReferenceException ex) {
throw new InvalidSortFieldException("The specified 'sortBy' value is invalid.");
}
}

/**
Expand Down Expand Up @@ -264,14 +271,19 @@ private BigDecimal calculateFineAmount(Borrowings borrowing) {
* @param memberId the ID of the member whose borrowings are to be retrieved
* @param pageable the pagination information, including the page number and size
* @throws ResourceNotFoundException if the member has not borrowed any books
* @throws InvalidSortFieldException if an invalid sortBy field is specified
* @return a {@link Page} of {@link Borrowings} representing all borrowing associated with a specific member
*/
public Page<Borrowings> getAllBorrowingsOfMember(int memberId, Pageable pageable) {
Page<Borrowings> borrowings = borrowingRepository.findByMember_memberId(memberId, pageable);

if (borrowings.isEmpty()) {
throw new ResourceNotFoundException("Member didn't borrow any book");
public Page<Borrowings> getAllBorrowingsOfMember(int memberId, Pageable pageable) {
try {
Page<Borrowings> borrowings = borrowingRepository.findByMember_memberId(memberId, pageable);

if (borrowings.isEmpty()) {
throw new ResourceNotFoundException("Member didn't borrow any book");
}
return borrowings;
} catch (PropertyReferenceException ex) {
throw new InvalidSortFieldException("The specified 'sortBy' value is invalid.");
}
return borrowings;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,20 @@ public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex,
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}

/**
* Handles {@link InvalidSortFieldException} exceptions.
* This method is triggered when an {@code InvalidSortFieldException} is thrown in the application.
* It constructs an {@link ErrorDetails} object containing the exception details and returns
* a {@link ResponseEntity} with an HTTP status of {@code 400 Bad Request}.
*
* @param ex the exception that was thrown.
* @param request the current web request in which the exception was thrown.
* @return a {@link ResponseEntity} containing the {@link ErrorDetails} and an HTTP status of {@code 400 Bad Request}.
*/
@ExceptionHandler(InvalidSortFieldException.class)
public ResponseEntity<?> invalidSortFieldException(InvalidSortFieldException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.libraryman_api.exception;

import java.io.Serial;

/**
* Custom exception class to handle scenarios where an invalid sort field
* is provided for API requests in the Library Management System.
* This exception is thrown when a sorting operation is attempted
* using a field that does not exist or is not supported.
*/
public class InvalidSortFieldException extends RuntimeException {

/**
* The {@code serialVersionUID} is a unique identifier for each version of a serializable class.
* It is used during the deserialization process to verify that the sender and receiver of a
* serialized object have loaded classes for that object that are compatible with each other.
*
* The {@code serialVersionUID} field is important for ensuring that a serialized class
* (especially when transmitted over a network or saved to disk) can be successfully deserialized,
* even if the class definition changes in later versions. If the {@code serialVersionUID} does not
* match during deserialization, an {@code InvalidClassException} is thrown.
*
* This field is optional, but it is good practice to explicitly declare it to prevent
* automatic generation, which could lead to compatibility issues when the class structure changes.
*
* The {@code @Serial} annotation is used here to indicate that this field is related to
* serialization. This annotation is available starting from Java 14 and helps improve clarity
* regarding the purpose of this field.
*/
@Serial
private static final long serialVersionUID = 1L;

/**
* Constructs a new {@code InvalidSortFieldException} with the specified detail message.
*
* @param message the detail message explaining the reason for the exception
*/
public InvalidSortFieldException(String message) {
super(message);
}

/**
* Constructs a new {@code InvalidSortFieldException} with the specified detail message and cause.
*
* @param message the detail message explaining the reason for the exception
* @param cause the cause of the exception (which is saved for later retrieval by the {@link #getCause()} method)
*/
public InvalidSortFieldException(String message, Throwable cause) {
super(message, cause);
}
}
9 changes: 8 additions & 1 deletion src/main/java/com/libraryman_api/member/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.stereotype.Service;

import com.libraryman_api.exception.InvalidSortFieldException;
import com.libraryman_api.exception.ResourceNotFoundException;
import com.libraryman_api.notification.NotificationService;

Expand Down Expand Up @@ -46,9 +48,14 @@ public MemberService(MemberRepository memberRepository, NotificationService noti
*
* @param pageable the pagination information, including the page number and size
* @return a {@link Page} of {@link Members} representing all members
* @throws InvalidSortFieldException if an invalid sortBy field is specified
*/
public Page<Members> getAllMembers(Pageable pageable) {
return memberRepository.findAll(pageable);
try {
return memberRepository.findAll(pageable);
} catch (PropertyReferenceException ex) {
throw new InvalidSortFieldException("The specified 'sortBy' value is invalid.");
}
}

/**
Expand Down
Loading