diff --git a/schools/src/main/java/com/lambdaschool/schools/exceptions/ResourceNotFoundException.java b/schools/src/main/java/com/lambdaschool/schools/exceptions/ResourceNotFoundException.java new file mode 100644 index 00000000..f9b182a1 --- /dev/null +++ b/schools/src/main/java/com/lambdaschool/schools/exceptions/ResourceNotFoundException.java @@ -0,0 +1,7 @@ +package com.lambdaschool.schools.exceptions; + +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String message) { + super(message); + } +} diff --git a/schools/src/main/java/com/lambdaschool/schools/handlers/RestExceptionHandler.java b/schools/src/main/java/com/lambdaschool/schools/handlers/RestExceptionHandler.java new file mode 100644 index 00000000..489f356a --- /dev/null +++ b/schools/src/main/java/com/lambdaschool/schools/handlers/RestExceptionHandler.java @@ -0,0 +1,52 @@ +package com.lambdaschool.schools.handlers; + +import com.lambdaschool.schools.exceptions.ResourceNotFoundException; +import com.lambdaschool.schools.models.ErrorDetail; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import java.util.Date; + +@Order(Ordered.HIGHEST_PRECEDENCE) +@RestControllerAdvice +public class RestExceptionHandler extends ResponseEntityExceptionHandler { + + public RestExceptionHandler() { super(); } + + @ExceptionHandler(ResourceNotFoundException.class) + public ResponseEntity handleResourceNotFoundException( + ResourceNotFoundException e + ) { + ErrorDetail errorDetail = new ErrorDetail(); + errorDetail.setTitle("Resource Not Found"); + errorDetail.setStatus(HttpStatus.NOT_FOUND.value()); + errorDetail.setDetail("Found an error with School: " + e.getMessage()); + errorDetail.setTimestamp(new Date()); + errorDetail.setDeveloperMessage(e.getClass().getName()); + return new ResponseEntity<>(errorDetail, HttpStatus.NOT_FOUND); + } + + @Override + protected ResponseEntity handleExceptionInternal( + Exception e, + Object body, + HttpHeaders headers, + HttpStatus status, + WebRequest request + ) { + ErrorDetail errorDetail = new ErrorDetail(); + errorDetail.setTitle("Rest Internal Error"); + errorDetail.setStatus(status.value()); + errorDetail.setDetail("Found an issue with School: " + e.getMessage()); + errorDetail.setTimestamp(new Date()); + errorDetail.setDeveloperMessage(e.getClass().getName()); + return new ResponseEntity<>(errorDetail, status); + } +} diff --git a/schools/src/main/java/com/lambdaschool/schools/models/ErrorDetail.java b/schools/src/main/java/com/lambdaschool/schools/models/ErrorDetail.java new file mode 100644 index 00000000..fd8a97b3 --- /dev/null +++ b/schools/src/main/java/com/lambdaschool/schools/models/ErrorDetail.java @@ -0,0 +1,65 @@ +package com.lambdaschool.schools.models; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class ErrorDetail { + private String title; + private int status; + private String detail; + private Date timestamp; + private String developerMessage; + private List errors = new ArrayList<>(); + + public ErrorDetail() { + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } + + public Date getTimestamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public String getDeveloperMessage() { + return developerMessage; + } + + public void setDeveloperMessage(String developerMessage) { + this.developerMessage = developerMessage; + } + + public List getErrors() { + return errors; + } + + public void setErrors(List errors) { + this.errors = errors; + } +} diff --git a/schools/src/main/java/com/lambdaschool/schools/models/ValidationError.java b/schools/src/main/java/com/lambdaschool/schools/models/ValidationError.java new file mode 100644 index 00000000..e57f3a52 --- /dev/null +++ b/schools/src/main/java/com/lambdaschool/schools/models/ValidationError.java @@ -0,0 +1,4 @@ +package com.lambdaschool.schools.models; + +public class ValidationError { +} diff --git a/schools/src/main/java/com/lambdaschool/schools/services/CoursesServiceImpl.java b/schools/src/main/java/com/lambdaschool/schools/services/CoursesServiceImpl.java index 77861321..5682d2a5 100644 --- a/schools/src/main/java/com/lambdaschool/schools/services/CoursesServiceImpl.java +++ b/schools/src/main/java/com/lambdaschool/schools/services/CoursesServiceImpl.java @@ -1,5 +1,6 @@ package com.lambdaschool.schools.services; +import com.lambdaschool.schools.exceptions.ResourceNotFoundException; import com.lambdaschool.schools.models.Course; import com.lambdaschool.schools.models.Instructor; import com.lambdaschool.schools.models.StudCourses; @@ -11,7 +12,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityNotFoundException; import java.util.ArrayList; import java.util.List; @@ -58,7 +58,7 @@ public List findAll() public Course findCourseById(long id) { return courserepos.findById(id) - .orElseThrow(() -> new EntityNotFoundException("Course id " + id + " not found!")); + .orElseThrow(() -> new ResourceNotFoundException("Course id " + id + " not found!")); } @Transactional @@ -66,7 +66,7 @@ public Course findCourseById(long id) public void delete(long id) { courserepos.findById(id) - .orElseThrow(() -> new EntityNotFoundException("Course id " + id + " not found!")); + .orElseThrow(() -> new ResourceNotFoundException("Course id " + id + " not found!")); courserepos.deleteById(id); } @@ -79,7 +79,7 @@ public Course save(Course course) if (course.getCourseid() != 0) { Course oldCourse = courserepos.findById(course.getCourseid()) - .orElseThrow(() -> new EntityNotFoundException("Course id " + course.getCourseid() + " not found!")); + .orElseThrow(() -> new ResourceNotFoundException("Course id " + course.getCourseid() + " not found!")); newCourse.setCourseid(course.getCourseid()); } @@ -87,7 +87,7 @@ public Course save(Course course) newCourse.setCoursename(course.getCoursename()); Instructor newInstructor = instructorrepos.findById(course.getInstructor() .getInstructorid()) - .orElseThrow(() -> new EntityNotFoundException("Instructor id " + course.getInstructor() + .orElseThrow(() -> new ResourceNotFoundException("Instructor id " + course.getInstructor() .getInstructorid() + " not found!")); newCourse.setInstructor(newInstructor); @@ -97,7 +97,7 @@ public Course save(Course course) { Student newStudent = studentrepos.findById(sc.getStudent() .getStudentid()) - .orElseThrow(() -> new EntityNotFoundException("Instructor id " + sc.getStudent() + .orElseThrow(() -> new ResourceNotFoundException("Instructor id " + sc.getStudent() .getStudentid() + " not found!")); newCourse.getStudents() diff --git a/schools/src/main/java/com/lambdaschool/schools/services/StudentServiceImpl.java b/schools/src/main/java/com/lambdaschool/schools/services/StudentServiceImpl.java index 1ad495cd..d25860d4 100644 --- a/schools/src/main/java/com/lambdaschool/schools/services/StudentServiceImpl.java +++ b/schools/src/main/java/com/lambdaschool/schools/services/StudentServiceImpl.java @@ -1,5 +1,6 @@ package com.lambdaschool.schools.services; +import com.lambdaschool.schools.exceptions.ResourceNotFoundException; import com.lambdaschool.schools.models.Course; import com.lambdaschool.schools.models.StudCourses; import com.lambdaschool.schools.models.Student; @@ -8,7 +9,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityNotFoundException; import java.util.ArrayList; import java.util.List; @@ -49,7 +49,7 @@ public List findAll() public Student findStudentById(long id) { return studentrepos.findById(id) - .orElseThrow(() -> new EntityNotFoundException("Student id " + id + " not found!")); + .orElseThrow(() -> new ResourceNotFoundException("Student id " + id + " not found!")); } @Transactional @@ -57,7 +57,7 @@ public Student findStudentById(long id) public void delete(long id) { studentrepos.findById(id) - .orElseThrow(() -> new EntityNotFoundException("Student id " + id + " not found!")); + .orElseThrow(() -> new ResourceNotFoundException("Student id " + id + " not found!")); studentrepos.deleteById(id); } @@ -70,7 +70,7 @@ public Student save(Student student) if (student.getStudentid() != 0) { Student oldStudent = studentrepos.findById(student.getStudentid()) - .orElseThrow(() -> new EntityNotFoundException("Student id " + student.getStudentid() + " not found!")); + .orElseThrow(() -> new ResourceNotFoundException("Student id " + student.getStudentid() + " not found!")); newStudent.setStudentid(student.getStudentid()); } diff --git a/schools/src/main/resources/application.properties b/schools/src/main/resources/application.properties index 9758fe0c..7d639673 100644 --- a/schools/src/main/resources/application.properties +++ b/schools/src/main/resources/application.properties @@ -23,3 +23,12 @@ spring.datasource.initialization-mode=always # spring.jpa.hibernate.ddl-auto=update # since we have our data in SeedData, do not also load it from data.sql # spring.datasource.initialization-mode=never +# +# Used to set the date format for JSON Output +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss +spring.jackson.time-zone=America/Los_Angeles +# +# Turns off Spring Boot automatic exception handling +server.error.whitelabel.enabled=false +spring.mvc.throw-exception-if-no-handler-found=true +spring.resources.add-mappings=false \ No newline at end of file