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

Global exception dev #4

Merged
merged 11 commits into from
Oct 22, 2023
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
<mapstruct.version>1.5.5.Final</mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.1.4</version>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no need to specify the version here

</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import com.example.springbootbookshop.dto.CreateBookRequestDto;
import com.example.springbootbookshop.entity.Book;
import com.example.springbootbookshop.service.BookService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -19,6 +22,7 @@

@RequiredArgsConstructor
@RestController
@Validated
@RequestMapping(value = "/books")
public class BookController {
private final BookService bookService;
Expand All @@ -37,20 +41,19 @@ public void deleteBookById(@PathVariable Long id) {

@GetMapping(value = "/{id}")
@ResponseStatus(HttpStatus.OK)
public BookDto getBookById(@PathVariable Long id) {
public BookDto getBookById(@PathVariable @Positive Long id) {
return bookService.getBookById(id);
}

@PutMapping(value = "/{id}")
@ResponseStatus(HttpStatus.ACCEPTED)
public BookDto getBookById(@RequestBody CreateBookRequestDto bookDto,
public BookDto getBookById(@RequestBody @Valid CreateBookRequestDto bookDto,
@PathVariable Long id) {
return bookService.update(bookDto, id);
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Book createBook(@RequestBody CreateBookRequestDto bookDto) {
public Book createBook(@RequestBody @Valid CreateBookRequestDto bookDto) {
return bookService.save(bookDto);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.example.springbootbookshop.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import java.math.BigDecimal;

public record CreateBookRequestDto(String title,
String author,
String isbn,
BigDecimal price,
public record CreateBookRequestDto(@NotBlank String title,
@NotBlank String author,
@NotBlank String isbn,
@NotNull @Positive BigDecimal price,
String description,
String coverImage) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.example.springbootbookshop.exception;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you have any other exceptions except for MethodArgumentNotValidException?

does it make sense to handle them as well?

MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatusCode status,
WebRequest request) {
Map<String,Object> body = new LinkedHashMap<>();
List<String> errors = ex.getBindingResult().getAllErrors().stream()
.map(this::getErrorMessage)
.toList();
body.put("errors", errors);
return new ResponseEntity<>(body,headers,status);
}

@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<Object> handleEntityNotFoundException(
EntityNotFoundException ex) {
System.out.println(ex.getMessage());
return new ResponseEntity<>(ex.getLocalizedMessage(), HttpStatus.BAD_REQUEST);
}

private String getErrorMessage(ObjectError e) {
if (e instanceof FieldError) {
String field = ((FieldError) e).getField();
String message = e.getDefaultMessage();
return String.format("%s %s",field,message);
}
return e.getDefaultMessage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import com.example.springbootbookshop.dto.BookDto;
import com.example.springbootbookshop.dto.CreateBookRequestDto;
import com.example.springbootbookshop.entity.Book;
import com.example.springbootbookshop.exception.EntityNotFoundException;
import com.example.springbootbookshop.mapper.BookMapper;
import com.example.springbootbookshop.repository.BookRepository;
import com.example.springbootbookshop.service.BookService;
import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
Expand Down
Loading