Как отличить неверные учетные данные для входа и сервер, недоступный с помощью JDBC - PullRequest
0 голосов
/ 24 апреля 2020

Я пишу программу для подключения к базе данных MariaDB через JDB C. С правильными учетными данными (имя пользователя / пароль) он подключается нормально. Но я пытаюсь выдавать соответствующие сообщения об ошибках, когда он не подключается, и именно здесь у меня возникает проблема. Я получаю те же исключения независимо от того, в чем проблема: сервер недоступен (остановлен) или учетные данные неверны.

В обоих случаях это дает:

SQL State: 42000
Error Code: -1
Message: No connection available within the specified time (option 'connectTimeout': 5,000 ms)
Cause: java.sql.SQLSyntaxErrorException: No connection available within the specified time (option 'connectTimeout': 5,000 ms)

Так что я могу Не объясните моему пользователю, нужно ли ему повторно вводить свой пароль или связываться с ИТ-отделом, потому что сервер не работает, потому что я не могу различить их.

Состояние SQL говорит мне, что это может быть либо синтаксическая ошибка или нарушение правил доступа. Я не смог найти ничего по коду ошибки '-1'.

Как я могу сделать это различие здесь?


Редактировать

Раньше мне не приходилось создавать минимально воспроизводимый пример, поэтому, надеюсь, это близко.

Это проект JavaFX F XML, и это контроллер для экрана входа в систему. Вы увидите, где я проверяю учетные данные и соединение внизу, плюс я прокомментировал определенный раздел c catch, с которым я борюсь.

public class ControllerLogin extends AnchorPane {

    //Initialise java fields
    public String UN;
    public String PW;

    private boolean credentialsAccepted;

    //Initialise fx fields
    @FXML   private TextField username;
    @FXML   private PasswordField password;

    //Initialise fx labels
    @FXML   private Label userMessage;

    //Constructor creates an FXML loader, set its properties and attempts to load the FXML file.
    public ControllerLogin() {
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(getClass().getResource("/fxml/LoginScreen.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        }
        catch (IOException exception) {
            throw new RuntimeException(exception);
        }

        userMessage.setVisible(false);

    }

    //Getters for username and password.

    public void getUsername(TextField name) {
        UN = name.getText();
    }

    public void getPassword(PasswordField pass) {
        PW = pass.getText();
    }

    //Event actions.

    public void run(ActionEvent event) {

        userMessage.setVisible(false);

        getUsername(username);
        getPassword(password);

        //Check field inputs.
        if (UN.isBlank()) {
            userMessage.setText("Username cannot be blank");
            userMessage.setVisible(true);
            return;
        } else if (PW.isBlank()) {
            userMessage.setText("Password cannot be blank");
            userMessage.setVisible(true);
            return;
        }

        DataSourceFactory loginCheck = new DataSourceFactory();

        Connection con = null;

        try {
            credentialsAccepted = false;
            con = loginCheck.createMariaDBPoolDataSource(UN, PW).getConnection();
            try {
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT CURRENT_USER");
                rs.first();
                final String currentUser = rs.getString("CURRENT_USER");
                if (currentUser.startsWith(UN + "@")) {
                    credentialsAccepted = true;
                }
                stmt.close();
                con.close();
            } catch (SQLException e) {
                System.out.println("Statement Error");
                System.err.println("SQL State: " + ((SQLException)e).getSQLState());
                System.err.println("Error Code: " + ((SQLException)e).getErrorCode());
                System.err.println("Message: " + ((SQLException)e).getMessage());
                System.err.println("Cause: " + ((SQLException)e).getCause());
                return;
            }

//The exception below does not tell me the difference between server offline
//and credentials incorrect, which is a problem for me because I want the
//user response message to be different depending on the outcome.
//I am not sure how to make it do what I want.
        } catch (SQLException e) {
            System.out.println("Login Failure");
            System.err.println("SQL State: " + ((SQLException)e).getSQLState());
            System.err.println("Error Code: " + ((SQLException)e).getErrorCode());
            System.err.println("Message: " + ((SQLException)e).getMessage());
            System.err.println("Cause: " + ((SQLException)e).getCause());
            return;
        }

        if (credentialsAccepted) {
            try {
                Stage homeStage = new Stage();
                ControllerHome home = new ControllerHome();
                homeStage.setScene(new Scene(home));
                homeStage.setTitle("Equipment Management Tool");
                homeStage.setResizable(true);
                homeStage.setWidth(1625);
                homeStage.setHeight(925);
                homeStage.setMaximized(true);
                homeStage.show();
                //Get the current stage (loginStage) and hide it so it disappears once you are logged in 
                Stage stage = (Stage) getScene().getWindow();
                stage.hide();
            } catch(Exception e) {
                e.printStackTrace();
                return;
            }
            return;
        } else {
            userMessage.setText("There was an unexpected error");
            userMessage.setVisible(true);
            return;
        }
    }
}

Это класс источника данных:

public class DataSourceFactory {

    public DataSource createMariaDBPoolDataSource(String username, String password) {
        Properties props = new Properties();
        InputStream inputStream;
        MariaDbPoolDataSource mariaDbPoolDS = null;
        try {
            inputStream = getClass().getResourceAsStream("/properties/db.properties");
            props.load(inputStream);
            mariaDbPoolDS = new MariaDbPoolDataSource();
            mariaDbPoolDS.setUrl(props.getProperty("MARIADB_DB_URL"));
            mariaDbPoolDS.setLoginTimeout(Integer.parseInt(props.getProperty("MARIADB_DB_LOGIN_TIMEOUT")));
            mariaDbPoolDS.setUser(username);
            mariaDbPoolDS.setPassword(password);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return mariaDbPoolDS;
    }
}

Это трассировки стека, возвращенные с неверными данными для входа и с неконтактируемым сервером, соответственно.

java.sql.SQLSyntaxErrorException: No connection available within the specified time (option 'connectTimeout': 5,000 ms)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:153)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.MariaDbPoolDataSource.getConnection(MariaDbPoolDataSource.java:239)
    at emtmodule/com.outlook.sensicalapp.emt.ControllerLogin.run(ControllerLogin.java:93)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8890)
    at javafx.controls/com.sun.javafx.scene.control.behavior.TextFieldBehavior.fire(TextFieldBehavior.java:184)
    at javafx.controls/com.sun.javafx.scene.control.behavior.TextInputControlBehavior.lambda$keyMapping$62(TextInputControlBehavior.java:330)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$KeyHandler.process(Scene.java:4070)
    at javafx.graphics/javafx.scene.Scene.processKeyEvent(Scene.java:2121)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2597)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
    at javafx.graphics/com.sun.glass.ui.View.handleKeyEvent(View.java:547)
    at javafx.graphics/com.sun.glass.ui.View.notifyKey(View.java:971)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.sql.SQLSyntaxErrorException: No connection available within the specified time (option 'connectTimeout': 5,000 ms)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:171)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.pool.Pool.getConnection(Pool.java:413)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.MariaDbPoolDataSource.getConnection(MariaDbPoolDataSource.java:237)
    ... 58 more
java.sql.SQLSyntaxErrorException: No connection available within the specified time (option 'connectTimeout': 5,000 ms)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:153)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.MariaDbPoolDataSource.getConnection(MariaDbPoolDataSource.java:239)
    at emtmodule/com.outlook.sensicalapp.emt.ControllerLogin.run(ControllerLogin.java:93)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8890)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3862)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2590)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.sql.SQLSyntaxErrorException: No connection available within the specified time (option 'connectTimeout': 5,000 ms)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:171)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.internal.util.pool.Pool.getConnection(Pool.java:413)
    at org.mariadb.jdbc@2.6.0/org.mariadb.jdbc.MariaDbPoolDataSource.getConnection(MariaDbPoolDataSource.java:237)
    ... 58 more

Примечание. Поскольку это В процессе работы здесь есть смесь различных стилей обработки исключений. Они будут исправлены, как только все заработает.

...