In a Spring Boot MVC application I have a controller which calls a service method:
@Controller
@RequestMapping("/registration")
public class RegistrationController {
@GetMapping({"/email-confirmation"})
public String emailConfirmation(@RequestParam String token) {
internalRegistrationService.confirmEmail(token);
return "redirect:/";
}
@ExceptionHandler(TokenExpiredException.class)
public ModelAndView handleTokenExpiredException(Exception e) {
ModelAndView mv = new ModelAndView();
//...
return mv;
}
}
This service method can throw different subtypes of TokenException
:
@Service
public class InternalRegistrationService {
public void confirmEmail(String token) throws TokenException {
emailTokenValidator.validate(token);
}
}
The thrown exception is either of type TokenException
or TokenExpiredException
, which extends TokenException.
Additionally to the @ExceptionHandler
inside the controller itself which catches the TokenExpiredException
as expected, I have a @ControllerAdvice
annotated GlobalExceptionHandler:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(TokenException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "out of cookies")
public void handleTokenException(Exception e) {
logger.debug("{}", e.getMessage(), e);
}
}
This handler method is meant to catch all other kinds of TokenException
but the TokenExpiredException
.
Unfortunately this doesn't work as intended. The exception is thrown inside a service method, which is called by the controller. According to this post from Antoniossss, all exceptions bubbling through the controller should get deligated to the
@ControllerAdvice
annotated GlobalExceptionHandler. However, it doesn't. Instead, the error results in an uncaught 500. Does anybody know why?
Many thanks for any help
Edit
Sometimes I'm asking myself whether to be only little stupid or complete plemplem. After an hour of trial and error, debugging and coffee with and without cookies I just stumbled across the fact, that I have forgotten to include the ControllerAdvice to classpath scanning. My deeply shame...
However, I will let this code here be, until someone of the crew thinks to better get rid of it.