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

fix: correct 404 not found responses and few test changes #137

Closed
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

package org.springframework.samples.petclinic.rest.advice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -33,23 +32,41 @@
import static org.springframework.http.HttpStatus.BAD_REQUEST;

/**
* Global Exception handler for REST controllers.
* <p>
* This class handles exceptions thrown by REST controllers and returns
* appropriate HTTP responses to the client.
*
* @author Vitaliy Fedoriv
* @author Alexander Dudkin
*/

@ControllerAdvice
public class ExceptionControllerAdvice {

@ExceptionHandler(Exception.class)
public ResponseEntity<String> exception(Exception e) {
ObjectMapper mapper = new ObjectMapper();
ErrorInfo errorInfo = new ErrorInfo(e);
String respJSONstring = "{}";
try {
respJSONstring = mapper.writeValueAsString(errorInfo);
} catch (JsonProcessingException e1) {
e1.printStackTrace();
/**
* Record for storing error information.
* <p>
* This record encapsulates the class name and message of the exception.
*
* @param className The name of the exception class
* @param exMessage The message of the exception
*/
private record ErrorInfo(String className, String exMessage) {
public ErrorInfo(Exception ex) {
this(ex.getClass().getName(), ex.getLocalizedMessage());
}
return ResponseEntity.badRequest().body(respJSONstring);
}

/**
* Handles all general exceptions by returning a 500 Internal Server Error status with error details.
*
* @param e The exception to be handled
* @return A {@link ResponseEntity} containing the error information and a 500 Internal Server Error status
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorInfo> handleGeneralException(Exception e) {
ErrorInfo info = new ErrorInfo(e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(info);
}

/**
Expand All @@ -73,13 +90,38 @@ public ResponseEntity<Void> handleMethodArgumentNotValidException(MethodArgument
return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST);
}

private class ErrorInfo {
public final String className;
public final String exMessage;
/**
* Handles {@link DataIntegrityViolationException} which typically indicates database constraint violations.
* This method returns a 404 Not Found status if an entity does not exist.
*
* @param ex The {@link DataIntegrityViolationException} to be handled
* @return A {@link ResponseEntity} containing the error information and a 404 Not Found status
*/
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseStatus(code = HttpStatus.NOT_FOUND)
@ResponseBody
public ResponseEntity<ErrorInfo> handleDataIntegrityViolationException(DataIntegrityViolationException ex) {
ErrorInfo errorInfo = new ErrorInfo(ex);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorInfo);
}

public ErrorInfo(Exception ex) {
this.className = ex.getClass().getName();
this.exMessage = ex.getLocalizedMessage();
/**
* Handles exception thrown by Bean Validation on controller methods parameters
*
* @param ex The thrown exception
* @return an empty response entity
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(BAD_REQUEST)
@ResponseBody
public ResponseEntity<ErrorInfo> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
BindingErrorsResponse errors = new BindingErrorsResponse();
BindingResult bindingResult = ex.getBindingResult();
if (bindingResult.hasErrors()) {
errors.addAllErrors(bindingResult);
return ResponseEntity.badRequest().body(new ErrorInfo("MethodArgumentNotValidException", "Validation failed"));
}
return ResponseEntity.badRequest().build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ void testAddPetError() throws Exception {
String newPetAsJSON = mapper.writeValueAsString(newPet);
given(this.clinicService.findPetById(999)).willReturn(null);
this.mockMvc.perform(post("/api/pets")
.content(new String()).accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
// empty content to force badRequest response
.content("{}").accept(MediaType.APPLICATION_JSON_VALUE).contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isBadRequest());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void testCreateUserSuccess() throws Exception {
void testCreateUserError() throws Exception {
User user = new User();
user.setUsername("username");
user.setPassword("password");
user.setPassword(""); // empty password to force badRequest Response
user.setEnabled(true);
ObjectMapper mapper = new ObjectMapper();
String newVetAsJSON = mapper.writeValueAsString(userMapper.toUserDto(user));
Expand Down
Loading