1

I know this is usually an issue that happens the other way around, so I am caught a little of guard here :D

I have built a user-management backend that provides a UI with data. When this architecture is deployed on our dev-server, everything works beautifully. However, as soon as I try to run the integration tests (which we do using a maven cargo tomcat) or if I use the war file in a local tomcat, the exception handlers aren't used at all. Spring simply displays a standard 500 response with the exception transformed into the body.

Perusing SO for similar issues has only resulted in the advice that I should use @EnableWebMVC, but that is neither applicable to what my backend is trying to accomplish, nor does it change anything.

How should I go about looking for the solution to this issue? Specifically, can I somehow observe if my controlleradvice is even scanned, and is there a reason why it might not be?

EDIT: These are the relevant files:

SpringConfiguration:

@Configuration
@ComponentScan(basePackageClasses = {UserManagementSpringConfiguration.class})
@EnableWebSecurity
public class UserManagementSpringConfiguration {

@Configuration
public static class ResourceMappingConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/ui/*/usermanagement").setViewName("forward:/usermanagement-ui/index.html");
//            registry.addViewController("/ui/*/*/generator/").setViewName("forward:/generator-ui/index.html");
        registry.addViewController("/ui/*/usermanagement/*").setViewName("forward:/usermanagement-ui/index.html");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // cache setting, otherwise fonts are not loaded in IE over https
        CacheControl cacheControl = CacheControl.noCache().mustRevalidate();
        registry.addResourceHandler("/ui/**/*").addResourceLocations("/usermanagement-ui/")
                    .setCacheControl(cacheControl);
        }

    }

}

ControllerAdvice:

@ControllerAdvice
public class CustomResponseEntityExceptionHandler {

    public static final Logger LOG = EISLoggerFactory.getLogger(CustomResponseEntityExceptionHandler.class);

    @PostConstruct
    public void postConstruct() {
        LOG.debug("CustomExceptionHandler loaded and ready for use");
    }

    @ExceptionHandler(PasswordMismatchException.class)
    public final ResponseEntity<ErrorDetails> handlePasswordChangeMismatch(
            PasswordMismatchException ex,
            WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(
                new Date(),
                ex.getMessage(),
                request.getDescription(false),
                MessageKeys.mismatchedPassword);
        return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
    }
}
7
  • 1
    Maybe adding in the controlleradvice a method which prints something in logs and annotate the method with @PostConstruct could help for debuging Commented Nov 27, 2018 at 12:59
  • @ValentinCarnu That's a really good idea! I'll try it and see what happens. Commented Nov 27, 2018 at 13:35
  • @ValentinCarnu It seems the ControllerAdvice is getting loaded. Just doesn't seem to be used. Commented Nov 27, 2018 at 15:54
  • does the application run as a war inside a tomcat server in the dev environment? Commented Nov 27, 2018 at 16:12
  • Yes. Just a Tomcat server. Commented Nov 28, 2018 at 8:42

1 Answer 1

1

It turns out that one of the modules that we wrote and that my project contains defines an ExceptionHandler for Throwable.class. On my machine, this ControllerAdvice is registered before my own ControllerAdvice, which causes Spring to look there first. Since Throwable fits the bill, Spring asks no further questions and just uses that handler.

The solution to my immediate problem was to add @Order(Ordered.HIGHEST_PRECEDENCE) to my ControllerAdvice. Since the exceptions I define within are quite specific, this will not cause any issues.

I have yet to find an explanation for why the order in which the two ControllerAdvice classes are registered is so consistently different between my machine and our dev server. Will update if I find anything. For now, I consider this issue to be answered.

This SO question was essential to solving this particular problem. Perhaps it helps someone in the future to link it here: Setting Precedence of Multiple @ControllerAdvice @ExceptionHandlers

Thanks to ValentinCarnu for pointing me to it!

Sign up to request clarification or add additional context in comments.

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.