Martin McKeaveney
Martin McKeaveney

Reputation: 508

Thread.setDefaultUncaughtExceptionHandler not being called in Spring Boot application

I am trying to implement a global uncaught exception handler in a spring boot application, which gathers metrics and exceptions etc from a bunch of client applications. It appears that the handler is being set when I debug, so I would assume that either another handler is assigned after my code runs, or these handlers are not set on the spring application context? My code is as follows.

I have created this class for my default exception handler -

public class JvmrtExceptionHandler implements Thread.UncaughtExceptionHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(JvmrtExceptionHandler.class);
private RestTemplate restTemplate = new RestTemplate();

@Override
public void uncaughtException(Thread thread, Throwable exception) {
    String exceptionClass = exception.getStackTrace()[0].getClassName();
    String exceptionMethod = exception.getStackTrace()[0].getMethodName();
    String exceptionMessage = exception.getMessage();
    String exceptionType = exception.getClass().getSimpleName();
    String appName = exception.getClass().getPackage().getImplementationTitle();
    ExceptionModel thrownException = new ExceptionModel(
            exceptionMessage,
            appName,
            exceptionMethod,
            exceptionClass,
            exceptionType
    );

    LOGGER.error("Uncaught Exception thrown of type {}. Sending to JVMRT Main app for processing", exceptionType);

    String exceptionUrl = String.format("http://%s:%s/api/", "localhost", 8090);
    restTemplate.postForObject(exceptionUrl, thrownException, String.class);



}

}

And this class, in another application which has the former application as a maven dependency, configures the default handler I have created. I would like the handler to work for all threads, so I have used the static Thread.setDefaultUncaughtExceptionHandler method to set it.

@Configuration
public class Config {

    @Bean
    public JvmrtExceptionHandler jvmrtExceptionHandler() {
        JvmrtExceptionHandler exceptionHandler = new JvmrtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
        return exceptionHandler;
    }
}

I am testing the handler with the following code.

@RestController
@RequestMapping(value = "/test")
public class ExceptionTest {

        @RequestMapping(value = "/exception", method = RequestMethod.GET)
        public void throwException() {
           throw new RuntimeException();
        }

}

What am I doing wrong? Really banging my head here, any help would be appreciated.

Upvotes: 0

Views: 2373

Answers (1)

wcong
wcong

Reputation: 601

Because your RuntimeException is caught by embed tomcat.you can find the try catch in org.apache.catalina.core.StandardWrapperValve.invoke. it print the full exception message,and put error in response.

if you want to catch exception in spring request mapping.you can try ControllerAdvice and ExceptionHandler.

Upvotes: 2

Related Questions