0

I have written the below Custom Error Handler in SPRING BOOT

@RestControllerAdvice 
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler
   // @ResponseBody
    public ResponseEntity<CustomErrorResponse> customHandleNotFound(Exception ex, WebRequest request) {

        CustomErrorResponse errors = new CustomErrorResponse();
        errors.setTimestamp(LocalDateTime.now());
        errors.setError(ex.getMessage());
        errors.setStatus(HttpStatus.CONFLICT.value());
        errors.setErrorMsg(errors.getErrorMsg());

        return  ResponseEntity.ok(errors);

    }

Below is my code Controller method

@RestController
@RequestMapping(value="/api")
public class AppController {




   @Autowired
    private UserRepository userRepository;



      @RequestMapping(value="/home/{id1}" ,method=RequestMethod.PUT)
     @ResponseBody
      public String home(@PathVariable("id1") Long idValue,    @RequestBody @Valid Student s)
    {

         System.out.println( " idValue is  "  + idValue);

        System.out.println( " Student -->" + s.getName()  + " -- "  + s.getId());


      return    "job done";

    }



      @RequestMapping("/foos")
    //  @ResponseBody
      public String getFoos(@RequestParam(value="t1",required=true)  String id)  {

          int i =1/0;

          System.out.println(" id is " + i++);
            return "ID: " + id + "  status: Success";
      }

The exception handler is working fine for the method getFoos() when it encounters 1/0 I get the output in POSTMAN as which is as expected

{
    "timestamp": "2019-08-04 11:24:22",
    "status": 409,
    "error": "/ by zero",
    "errorMsg": "ERROR-msg"
}

But in my home() method I deliberately made Student object as invalid and I get no error message in POSTMAN but just in the eclipse console. Why?

I get this message.So how do I kick in CustomGlobalExceptionHandler when the Student object is invalid

2019-08-04 23:25:57.551 WARN 9652 --- [nio-8080-exec-6] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.String com.example.hibernatemapping.controller.AppController.home(java.lang.Long,com.example.hibernatemapping.domain.Student)]

Raj R
  • 63
  • 1
  • 3
  • 11
  • Add `@ExceptionHandler({HttpMessageNotReadableException.class, Exception.class})` – Jonathan JOhx Aug 04 '19 at 18:42
  • my server doesn't eve n start now after adding – Raj R Aug 04 '19 at 18:50
  • Ambiguous @ExceptionHandler method mapped for [class org.springframework.http.converter.HttpMessageNotReadableException]: {public org.springframework.http.ResponseEntity com.example.hibernatemapping.exception.CustomGlobalExceptionHandler.customHandleNotFound(java.lang.Exception,org.springframework.web.context.request.WebRequest), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) – Raj R Aug 04 '19 at 18:50
  • Okay so just @ExceptionHandler(Exception.class) – Jonathan JOhx Aug 04 '19 at 18:55
  • it doesn't work for home() method – Raj R Aug 04 '19 at 18:57
  • Okay if you create a new method for that handler on that exception? `@ExceptionHandler(HttpMessageNotReadableException.class)` looks like it is an exception in RunTime is not caught by the handlers, so please do that and let me how it goes. – Jonathan JOhx Aug 04 '19 at 18:59
  • so you have @Valid Student s and the ExceptionHandler ? Wich should be triggered ? Try to remove the Valid Student s from your home() method – AchillesVan Aug 04 '19 at 19:04
  • I solved it thank you – Raj R Aug 04 '19 at 19:08

2 Answers2

0

Well, there are many things to say.

First, exception handlers take an exception class as parameter, which allow you to return other errors following the exception class you throw in a controller method.

The one you wrote catch all exceptions and return the same error model, which is not a right idea. The right way to do is to write an abstract class AbstractMyAppException that extends Exception, and then implement a new class that extends of it for every error case you have.

Then, add two @ExceptionHandler :

  • One bind on the AbstractMyAppException class that return all errors that your app generate
  • One bind on the Exception class that return all other errors that should not happen.

For your case, it seems that you are using Spring Validation (you are using @Valid annotation). So make sure that you have followed this tutorial.

Then, your question is about catching validation errors to show a custom message if a student is invalid. Then check this thread.

  • it doesn't answer my question.More over this answer confused me – Raj R Aug 04 '19 at 18:17
  • Then sorry, but your question is not very clear ... Could you specify what do you want to know exactly ? – Jordan Lefébure Aug 04 '19 at 18:19
  • I want the home() to return the error is the same format as ` { "timestamp": "2019-08-04 11:24:22", "status": 409, "error": "/ by zero", "errorMsg": "ERROR-msg" }` This is my CustomErrorResponse class fields – Raj R Aug 04 '19 at 18:21
0

I solved it by adding the below in my ControllerAdviceI will just change the code to map error to my custom Pojo class CustomErrorResponse

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers,
                                                                  HttpStatus status, WebRequest request) {

        Map<String, Object> body = new LinkedHashMap<>();
        body.put("timestamp", new Date());
        body.put("status", status.value());

        //Get all errors
        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(x -> x.getDefaultMessage())
                .collect(Collectors.toList());

        body.put("errors", errors);

         System.out.println( " erro here ");
        return new ResponseEntity<>(body, headers, status);


}
Raj R
  • 63
  • 1
  • 3
  • 11