Calabacin
Calabacin

Reputation: 735

How can I control exceptions on Spring Boot startup?

My Spring Boot application tries to load some certificate files on startup. I want to be able to show a sensible message when that file cannot be loaded instead of a huge stack trace.

The certificate file is being loaded in a @PostConstruct method inside a @Component class. If it throws a FileNotFoundException I catch it and throw a specific exception that I created. I need to throw an exception in any case because I don't want the application to load if that file is not read.

I tried this:

@SpringBootApplication
public class FileLoadTestApplication {
    public static void main(String[] args) {
        try {
            SpringApplication.run(FileLoadTestApplication .class, args);
        } catch (Exception e) {
            LOGGER.error("Application ending due to an error.");
            if (e.getClass().equals(ConfigException.class)) {
                if (e.getCause().getClass().equals(FileNotFoundException.class)) {
                    LOGGER.error("Unable to read file: " + e.getCause().getMessage());
                } else {
                    LOGGER.error("Initial configuration failed.", e.getCause());
                }
            }
        }
    }
}

but the exception is not thrown inside inside the run method.

How can I control some exceptions on startup so that I show an informative message before closing?

Upvotes: 4

Views: 6664

Answers (1)

pulkit-singhal
pulkit-singhal

Reputation: 847

You can catch the BeanCreationException and unwrap it to get the original cause. You can use the following code fragment

public static void main(String[] args) {
    try {
        SpringApplication.run(FileLoadTestApplication.class, args);
    } catch (BeanCreationException ex) {
        Throwable realCause = unwrap(ex);
        // Perform action based on real cause
    }
}

public static Throwable unwrap(Throwable ex) {
    if (ex != null && BeanCreationException.class.isAssignableFrom(ex.getClass())) {
        return unwrap(ex.getCause());
    } else {
        return ex;
    }
}

When the @PostConstruct annotated method throws an exception, Spring wraps it inside the BeanCreationException and throws back.

Upvotes: 4

Related Questions