Skip to content

Commit ec6d134

Browse files
UUID added to error response, to be uniquely identifiable on logging solutions, e.g. ELK
1 parent 47446df commit ec6d134

File tree

5 files changed

+26
-19
lines changed

5 files changed

+26
-19
lines changed

lemon-demo-jpa/src/test/java/com/naturalprogrammer/spring/lemondemo/SignupMvcTests.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
import com.naturalprogrammer.spring.lemon.commons.util.LecUtils;
44
import com.naturalprogrammer.spring.lemondemo.entities.User;
55
import org.junit.jupiter.api.Test;
6+
import org.springframework.http.HttpStatus;
67
import org.springframework.http.MediaType;
78
import org.springframework.test.context.jdbc.Sql;
89

10+
import javax.validation.ConstraintViolationException;
11+
912
import static org.hamcrest.Matchers.*;
1013
import static org.junit.jupiter.api.Assertions.assertNotEquals;
1114
import static org.mockito.ArgumentMatchers.any;
@@ -26,15 +29,20 @@ void testSignupWithInvalidData() throws Exception {
2629
.contentType(MediaType.APPLICATION_JSON)
2730
.content(LecUtils.toJson(invalidUser)))
2831
.andExpect(status().is(422))
29-
.andExpect(jsonPath("$.errors[*].field").value(hasSize(4)))
30-
.andExpect(jsonPath("$.errors[*].field").value(hasItems(
32+
.andExpect(jsonPath("id").isString())
33+
.andExpect(jsonPath("exceptionId").value(ConstraintViolationException.class.getSimpleName()))
34+
.andExpect(jsonPath("error").value("Unprocessable Entity"))
35+
.andExpect(jsonPath("message").value("Validation Error"))
36+
.andExpect(jsonPath("status").value(HttpStatus.UNPROCESSABLE_ENTITY.value()))
37+
.andExpect(jsonPath("errors[*].field").value(hasSize(4)))
38+
.andExpect(jsonPath("errors[*].field").value(hasItems(
3139
"user.email", "user.password", "user.name")))
32-
.andExpect(jsonPath("$.errors[*].code").value(hasItems(
40+
.andExpect(jsonPath("errors[*].code").value(hasItems(
3341
"{com.naturalprogrammer.spring.invalid.email}",
3442
"{blank.name}",
3543
"{com.naturalprogrammer.spring.invalid.email.size}",
3644
"{com.naturalprogrammer.spring.invalid.password.size}")))
37-
.andExpect(jsonPath("$.errors[*].message").value(hasItems(
45+
.andExpect(jsonPath("errors[*].message").value(hasItems(
3846
"Not a well formed email address",
3947
"Name required",
4048
"Email must be between 4 and 250 characters",

spring-lemon-commons-web/src/main/java/com/naturalprogrammer/spring/lemon/commonsweb/exceptions/LemonErrorAttributes.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.naturalprogrammer.spring.lemon.exceptions.ErrorResponseComposer;
44
import com.naturalprogrammer.spring.lemon.exceptions.util.LexUtils;
5+
import lombok.extern.slf4j.Slf4j;
56
import org.apache.commons.logging.Log;
67
import org.apache.commons.logging.LogFactory;
78
import org.springframework.boot.web.error.ErrorAttributeOptions;
@@ -15,13 +16,11 @@
1516
* <code>DefaultExceptionHandlerControllerAdvice</code>,
1617
* e.g. exceptions thrown in filters.
1718
*/
19+
@Slf4j
1820
public class LemonErrorAttributes<T extends Throwable> extends DefaultErrorAttributes {
1921

20-
private static final Log log = LogFactory.getLog(LemonErrorAttributes.class);
21-
2222
static final String HTTP_STATUS_KEY = "httpStatus";
23-
24-
private ErrorResponseComposer<T> errorResponseComposer;
23+
private final ErrorResponseComposer<T> errorResponseComposer;
2524

2625
public LemonErrorAttributes(ErrorResponseComposer<T> errorResponseComposer) {
2726

spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/ErrorResponse.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22

33
import lombok.Getter;
44
import lombok.Setter;
5+
import lombok.ToString;
56

67
import java.util.Collection;
78

89
/**
910
* Error DTO, to be sent as response body
1011
* in case of errors
1112
*/
12-
@Getter @Setter
13+
@Getter @Setter @ToString
1314
public class ErrorResponse {
14-
15+
16+
private String id;
1517
private String exceptionId;
1618
private String error;
1719
private String message;

spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/LemonFieldError.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,22 @@
1616

1717
/**
1818
* Holds a field or form error
19-
*
20-
* @author Sanjay Patel
2119
*/
2220
@Getter @AllArgsConstructor @ToString
2321
public class LemonFieldError implements Serializable {
2422

2523
// Name of the field. Null in case of a form level error.
26-
private String field;
24+
private final String field;
2725

2826
// Error code. Typically the I18n message-code.
29-
private String code;
27+
private final String code;
3028

3129
// Error message
32-
private String message;
30+
private final String message;
3331

3432
/**
3533
* Converts a set of ConstraintViolations
3634
* to a list of FieldErrors
37-
*
38-
* @param constraintViolations
3935
*/
4036
public static List<LemonFieldError> getErrors(
4137
Set<ConstraintViolation<?>> constraintViolations) {

spring-lemon-exceptions/src/main/java/com/naturalprogrammer/spring/lemon/exceptions/handlers/AbstractExceptionHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.springframework.http.HttpStatus;
99

1010
import java.util.Collection;
11+
import java.util.UUID;
1112

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

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

19-
private Class<?> exceptionClass;
20+
private final Class<?> exceptionClass;
2021

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

4748
ErrorResponse errorResponse = new ErrorResponse();
48-
49+
50+
errorResponse.setId(UUID.randomUUID().toString());
4951
errorResponse.setExceptionId(getExceptionId(ex));
5052
errorResponse.setMessage(getMessage(ex));
5153

0 commit comments

Comments
 (0)