As you can see, I used two error-catching methods with the same parameters, but when I run it, I get the following error. The reason I use them the same is because spring boot also throws the same exception @Email and @Size so I want to catch them and show my own error output. How can I run both at different times without an error? For example, when you do not type the @ symbol, I want to show my own error by flashing the related error output, or if the password length is short, I want to show the related error output.
org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerExceptionResolver]: Factory method 'handlerExceptionResolver' threw exception; nested exception is java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class javax.validation.ConstraintViolationException]: {public az.expressbank.task.response.ExceptionResponse az.expressbank.task.api.controller.EmployeeRestApiExceptionHandlerController.catchWhenTypeWrongEmailRegisterPage(javax.validation.ConstraintViolationException), public az.expressbank.task.response.ExceptionResponse az.expressbank.task.api.controller.EmployeeRestApiExceptionHandlerController.catchWhenTypeShortPasswordRegisterPage(javax.validation.ConstraintViolationException)}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ExceptionResponse catchWhenTypeWrongEmailRegisterPage(ConstraintViolationException exception) {
Exception exception1=new Exception();
ExceptionResponse exceptionResponse = new ExceptionResponse();
exceptionResponse.setMessage(Message.PASSWORD_MUST_NOT_BE_SHORT.getMessage());
exceptionResponse.setCode(550);
return exceptionResponse;
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ExceptionResponse catchWhenTypeShortPasswordRegisterPage(ConstraintViolationException exception) {
ExceptionResponse exceptionResponse = new ExceptionResponse();
exceptionResponse.setMessage(Message.WRONG_FORMAT.getMessage());
exceptionResponse.setCode(551);
return exceptionResponse;
}
CodePudding user response:
You can only have one exception handler for each type of the exception. That means you have to rely on checking the state of the exception instance to determine the root cause of the failure.
Please note that it will throw ConstraintViolationException
if it fails to validate on @PathVariable
or @RequestParam
while throw MethodArgumentNotValidException
instead if fails on validating the request body.
For ConstraintViolationException
, you can refer to this example for how to define the error code for each validator and find out the correspond error code of that failure validator.
For MethodArgumentNotValidException
, you can refer to the following codes for the ideas to find out which validators causes the failure .
@ExceptionHandler(MethodArgumentNotValidException.class)
public ExceptionResponse handle(MethodArgumentNotValidException exp) {
BindingResult bindingResult = exp.getBindingResult();
bindingResult.getAllErrors().forEach(err -> {
err.getCode() // simple class name of the validator annotation that cause the exception such as Email /Size
err.getDefaultMessage ()
});
}