0

when native query fails to execute which method of restcontrolleradvice class would be executed between sqlgrammar exception and Exception

@RestControllerAdvice public class ExceptionControllerAdvice {

@Autowired
Helper HelperUtilities;

@Autowired
HttpServletRequest request;

@Autowired
Telemetry tel;




@ExceptionHandler(SQLGrammarException.class)
public ResponseEntity<ErrorResponse> exceptionHandler(SQLGrammarException ex) {
    ex.printStackTrace();
    ErrorResponse error = new ErrorResponse();
    error.setErrorCode(500);
    error.setMessage(ex.getMessage());

    // Log this error in Kibana using stdout
    String CurrentUser = HelperUtilities.getCurrentUserNameFromJWT();
    String ErrorDetails = "Server Side Error (UnHandled):: User - " + CurrentUser
            + " ::: Method  - exceptionHandler(Exception ex) :: Error Details - "
            + HelperUtilities.getStackTraceAsString(ex);

    return new ResponseEntity<ErrorResponse>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex)  {
    ex.printStackTrace();
    ErrorResponse error = new ErrorResponse();
    error.setErrorCode(400);
    error.setMessage(ex.getLocalizedMessage());
    String CurrentUser = HelperUtilities.getCurrentUserNameFromJWT();
    String ErrorDetails = "Server Side Error (UnHandled):: User - " + CurrentUser
            + " ::: Method  - exceptionHandler(Exception ex) :: Error Details - "
            + HelperUtilities.getStackTraceAsString(ex);
    tel.setExeceptionEventData( HttpStatus.BAD_REQUEST.toString(),ErrorDetails, new Object() {
    }.getClass().getEnclosingMethod().getName());
    return new ResponseEntity<ErrorResponse>(error, HttpStatus.INTERNAL_SERVER_ERROR);

}

1 Answers1

0

Spring will call the ExceptionHandler in the same order they are registered in SpringContext. Use @Order or @Priority annotation to ensure that the more specific ExceptionHandler is registered first. In your case something like

@Order(1)
@ExceptionHandler(SQLGrammarException.class)
public ResponseEntity<ErrorResponse> exceptionHandler(SQLGrammarException ex) 
{
   ....
}

@Order(2)
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex)  {
  ....
}

Answer found here by searching in google for "spring multiple exceptionhandler": Setting Precedence of Multiple @ControllerAdvice @ExceptionHandlers

So the point here is: if you have a @ControllerAdvice with an @ExceptionHandler for Exception that gets registered before another @ControllerAdvice class with an @ExceptionHandler for a more specific exception, like IOException, that first one will get called. As mentioned earlier, you can control that registration order by having your @ControllerAdvice annotated class implement Ordered or annotating it with @Order or @Priority and giving it an appropriate value.

DCO
  • 1,222
  • 12
  • 24
  • So, according to you, SQLGrammarException will execute first as it is placed before Exception? – Anmol Thakur May 13 '20 at 12:45
  • No - not because its position in your source code - This is just your source code and as you know it will be compiled to class files afterwards - So the position of your exceptionhandlers in your code does not ensure any order - BUT as you see in my example I added @Order annotation which ensures an order. – DCO May 14 '20 at 06:58
  • so what should ideally execute when we are not going to use order annotation,as what i think the parent @ExceptionHandler(Exception.class) should execute in last .i mean when @ExceptionHandler(SQLGrammarException.class) this method will not be there then it should go to parent exception ,child one should executes first and i have only one controller advice class that is shown above. – Anmol Thakur May 15 '20 at 09:43