Skip to content

Commit

Permalink
Merge pull request #56 from Guhapriya01/feature/pagination-sorting-api
Browse files Browse the repository at this point in the history
Improve Exception Handling for Invalid Sort Fields
  • Loading branch information
ajaynegi45 authored Oct 3, 2024
2 parents e8905ac + a6deb44 commit ba96678
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 9 deletions.
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

0 comments on commit ba96678

Please sign in to comment.