如何捕获SpringBootApplication抛出的特定异常消息?

cs7cruho  于 2023-06-22  发布在  Spring
关注(0)|答案(1)|浏览(104)

我有一个连接到数据库的Sping Boot 应用程序。主类是这样的:

@SpringBootApplication
public class OurApplication {
    public static void main(String[] args) {
        try {
            SpringApplication.run(OurApplication.class, args); // this is line 27
        }
        catch (Exception e) {
            Throwable t = e;
            while (t != null) {
                System.out.println("MESSAGE="+t.getMessage());
                t = t.getCause();
            }
        }
    }
}

我想捕捉任何抛出的异常,如果错误消息如下,那么我将以某种方式处理它:

java.sql.SQLSyntaxErrorException: Access denied for user 'service-account'@'%' to database 'our_database'

问题是上面代码中的catch (Exception e)块没有捕捉到特定的异常。当我运行应用程序时,我看到以下输出(一些堆栈跟踪已被修剪):

2023-06-06 13:38:52.988 ERROR 3040 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.

java.sql.SQLSyntaxErrorException: Access denied for user 'service-account'@'%' to database 'our_database'
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:824)
    [...]
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    [...]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
    at com.mycompany.mypackage.OurApplicationApplication.main(OurApplicationApplication.java:27)

2023-06-06 13:38:52.988  WARN 3040 --- [           main] o.h.e.j.e.i.JdbcEnvironmentInitiator     : HHH000342: Could not obtain connection to query metadata

java.sql.SQLSyntaxErrorException: Access denied for user 'service-account'@'%' to database 'our_database'
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:824)
    [...]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
    [...]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
    at com.mycompany.mypackage.OurApplicationApplication.main(OurApplicationApplication.java:27)

2023-06-06 13:38:52.988 ERROR 3040 --- [           main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
2023-06-06 13:38:52.997  WARN 3040 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
2023-06-06 13:38:52.997  INFO 3040 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-06-06 13:38:53.037  INFO 3040 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-06-06 13:38:53.077 ERROR 3040 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    [...]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
    at com.mycompany.mypackage.OurApplicationApplication.main(OurApplicationApplication.java:27)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    [...]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 16 common frames omitted
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100)
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:138)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    ... 33 common frames omitted

MESSAGE=Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
MESSAGE=Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
MESSAGE=Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

Process finished with exit code 0

首先,从OurApplicationApplication.main(OurApplicationApplication.java:27)开始的堆栈跟踪被打印出来,即使在第27行周围有一个try/catch (Exception e),并且catch块没有打印出整个堆栈跟踪。这怎么可能?
其次,在输出的底部,您可以看到MESSAGE=消息,它们为链中的每个异常打印出消息。为什么不打印出从堆栈跟踪中可以看到的Access denied for user 'service-account'@'%' to database 'our_database'消息?

zf9nrax1

zf9nrax11#

尝试以下解决方案:
Sping Boot 中的异常处理程序通常涉及@ExceptionHandler注解的使用。通过使用@ExceptionHandler注解方法,您可以定义应用程序应该如何处理特定的异常。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<String> handleNotFoundException(NotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred");
    }
}

=>它通常用于spring Boot 中的全局异常处理

相关问题