1

Sample Project Attached Here

I am following this article API Error Handling (also please suggest if there is a better way to do this) to handle exceptions and validations in a generic way in my spring boot rest service. (i am new to spring and rest, so i am going through different articles for my requirement)

Basic idea about the requirement:

(Need to validate the POST request and send the validation errors to the client in a structure way. There could be multiple validation errors)

Whenever i get a POST request from my client, i need to validate the RequestBody. So I added @Valid on the parameter and @NotNull on the properties which i want to validate. Upon receiving the POST request spring is validating the request and throwing MethodArgumentNotValidException which is fine since i have some mandatory field missing. I am handling it in a common place with @ControllerAdvice. After hitting the appropriate method handleMethodArgumentNotValid(...), i am constructing my custom error response APICustomError which i following from the above mentioned article.

When i have multiple validation errors, i am able to loop all the errors and adding it to a list and constructing the ResponseEntity with my custom error. But the returned ResponseEntity does not have my added validation errors.

i understood the article and implemented the same in my project but really didn't get what i am missing.

The below is the output said in the article and what i am expecting is:

{
   "apierror":{
      "status":"BAD_REQUEST",
      "timestamp":"10-07-2019 12:53:24",
      "message":"Validation error",
      "subErrors":[
         {
            "object":"person",
            "field":"id",
            "rejectedValue":null,
            "message":"ID cannot be null"
         },
         {
            "object":"person",
            "field":"name",
            "rejectedValue":null,
            "message":"name cannot be null"
         }
      ]
   }
}

but below is what i am getting. i don't see the subErrors part at all.

{"message":"Validation Error","debugMessage":null,"detail":null,"httpStatus":"BAD_REQUEST","timestamp":"2019-07-10T17:08:00.52"}

Any help is appreciated.

3
  • Hello Saravana, Any errors? Also, share the suspected code instead of the whole project Commented Jul 10, 2019 at 12:29
  • can you please share on which controller endpoint you are making request Commented Jul 10, 2019 at 12:35
  • I am doing in the PersonController. Because of @Valid even before my return it is getting validated in my RestCustomExceptionHandler but the returned response doesn't have the subErrors part. Can you take a look at my code from github Commented Jul 10, 2019 at 12:41

2 Answers 2

2

You need to add getter and setters in APICustomError for properly serialize your object. Also you need public constructor and getter/setters for inner class APIValidationError. I suggest you use Lombok.

After that you will see the errors, something like this...

{
   "message": "Validation Error",
   "debugMessage": null,
   "subErrors": [
       {
           "object": "personDTO",
           "field": "id",
           "rejectedValue": null,
           "validationErrorMessage": "ID cannot be null."
       }
   ],
   "detail": null,
   "httpStatus": "BAD_REQUEST",
   "timestamp": "2019-07-10T10:25:44.1705441"
}
Sign up to request clarification or add additional context in comments.

4 Comments

The response format is a lot cluttered. The code from this article toptal.com/java/spring-boot-rest-api-error-handling produces the below output which is what i am expecting. {"apierror":{"status":"BAD_REQUEST","timestamp":"10-07-2019 06:41:32","message":"Validation error","subErrors":[{"object":"bird","field":"mass","rejectedValue":1.0E7,"message":"must be less than or equal to 104000"}]}}
I missed that you were using an inner class in APICustomError, previous response was not you error handler. Now it is.
Great! After adding getters and setters. it is working as expected. Thanks a lot. Just a small question? Is this approach, a better of handling validations?
As far as i know this is a good approach for proper error handling. In this cas you only use it for formatting, but it is a very common practice. Regards.
0

Try this one In your controller advice

protected ResponseEntity<Object> handleMethodArgumentNotValid(
                MethodArgumentNotValidException ex,
                HttpHeaders headers, 
                HttpStatus status, WebRequest request) {
    Response response = new Response();
    List<FieldError> errors = ex.getBindingResult().getFieldErrors();
    List<SubError> errors = new ArrayList<>();

    for (FieldError e : errors) {
        SubError error = new SubError():
        error.setMessage(String.format(MESSAGE_FORMAT, egetCOde));
        errors.add(error);
    }
    response.setSubError(errors);
    return new ResponseEntity(response, HttpStatus.BAD_REQUEST);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.