Skip to content

Commit

Permalink
UUID added to error response, to be uniquely identifiable on logging …
Browse files Browse the repository at this point in the history
…solutions, e.g. ELK
  • Loading branch information
naturalprogrammer committed Jul 19, 2020
1 parent 47446df commit ec6d134
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 19 deletions.
Expand Up @@ -3,9 +3,12 @@
import com.naturalprogrammer.spring.lemon.commons.util.LecUtils;
import com.naturalprogrammer.spring.lemondemo.entities.User;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;

import javax.validation.ConstraintViolationException;

import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.mockito.ArgumentMatchers.any;
Expand All @@ -26,15 +29,20 @@ void testSignupWithInvalidData() throws Exception {
.contentType(MediaType.APPLICATION_JSON)
.content(LecUtils.toJson(invalidUser)))
.andExpect(status().is(422))
.andExpect(jsonPath("$.errors[*].field").value(hasSize(4)))
.andExpect(jsonPath("$.errors[*].field").value(hasItems(
.andExpect(jsonPath("id").isString())
.andExpect(jsonPath("exceptionId").value(ConstraintViolationException.class.getSimpleName()))
.andExpect(jsonPath("error").value("Unprocessable Entity"))
.andExpect(jsonPath("message").value("Validation Error"))
.andExpect(jsonPath("status").value(HttpStatus.UNPROCESSABLE_ENTITY.value()))
.andExpect(jsonPath("errors[*].field").value(hasSize(4)))
.andExpect(jsonPath("errors[*].field").value(hasItems(
"user.email", "user.password", "user.name")))
.andExpect(jsonPath("$.errors[*].code").value(hasItems(
.andExpect(jsonPath("errors[*].code").value(hasItems(
"{com.naturalprogrammer.spring.invalid.email}",
"{blank.name}",
"{com.naturalprogrammer.spring.invalid.email.size}",
"{com.naturalprogrammer.spring.invalid.password.size}")))
.andExpect(jsonPath("$.errors[*].message").value(hasItems(
.andExpect(jsonPath("errors[*].message").value(hasItems(
"Not a well formed email address",
"Name required",
"Email must be between 4 and 250 characters",
Expand Down
Expand Up @@ -2,6 +2,7 @@

import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer;
import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.web.error.ErrorAttributeOptions;
Expand All @@ -15,13 +16,11 @@
* <code>DefaultExceptionHandlerControllerAdvice</code>,
* e.g. exceptions thrown in filters.
*/
@Slf4j
public class LemonErrorAttributes<T extends Throwable> extends DefaultErrorAttributes {

private static final Log log = LogFactory.getLog(LemonErrorAttributes.class);

static final String HTTP_STATUS_KEY = "httpStatus";

private ErrorResponseComposer<T> errorResponseComposer;
private final ErrorResponseComposer<T> errorResponseComposer;

public LemonErrorAttributes(ErrorResponseComposer<T> errorResponseComposer) {

Expand Down
Expand Up @@ -2,16 +2,18 @@

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.Collection;

/**
* Error DTO, to be sent as response body
* in case of errors
*/
@Getter @Setter
@Getter @Setter @ToString
public class ErrorResponse {


private String id;
private String exceptionId;
private String error;
private String message;
Expand Down
Expand Up @@ -16,26 +16,22 @@

/**
* Holds a field or form error
*
* @author Sanjay Patel
*/
@Getter @AllArgsConstructor @ToString
public class LemonFieldError implements Serializable {

// Name of the field. Null in case of a form level error.
private String field;
private final String field;

// Error code. Typically the I18n message-code.
private String code;
private final String code;

// Error message
private String message;
private final String message;

/**
* Converts a set of ConstraintViolations
* to a list of FieldErrors
*
* @param constraintViolations
*/
public static List<LemonFieldError> getErrors(
Set<ConstraintViolation<?>> constraintViolations) {
Expand Down
Expand Up @@ -8,6 +8,7 @@
import org.springframework.http.HttpStatus;

import java.util.Collection;
import java.util.UUID;

/**
* Extend this to code an exception handler
Expand All @@ -16,7 +17,7 @@ public abstract class AbstractExceptionHandler<T extends Throwable> {

protected final Log log = LogFactory.getLog(this.getClass());

private Class<?> exceptionClass;
private final Class<?> exceptionClass;

public AbstractExceptionHandler(Class<?> exceptionClass) {
this.exceptionClass = exceptionClass;
Expand Down Expand Up @@ -45,7 +46,8 @@ protected Collection<LemonFieldError> getErrors(T ex) {
public ErrorResponse getErrorResponse(T ex) {

ErrorResponse errorResponse = new ErrorResponse();


errorResponse.setId(UUID.randomUUID().toString());
errorResponse.setExceptionId(getExceptionId(ex));
errorResponse.setMessage(getMessage(ex));

Expand Down

0 comments on commit ec6d134

Please sign in to comment.