From 22c11b3eebb74b27beadb0fa2f2f35dff64b1105 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 14 Jan 2024 15:05:47 -0600 Subject: [PATCH] Fix repo connection closed not thrown/handled correctly --- .../core/sql/AbstractDhRepo.java | 54 +++++++++++++------ .../core/sql/DbConnectionClosedException.java | 27 +++++----- 2 files changed, 51 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/sql/AbstractDhRepo.java b/core/src/main/java/com/seibel/distanthorizons/core/sql/AbstractDhRepo.java index caab188ae..00b30dbdf 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/sql/AbstractDhRepo.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/sql/AbstractDhRepo.java @@ -139,8 +139,9 @@ public abstract class AbstractDhRepo { this.query(statement); } - catch (DbConnectionClosedException ignored) + catch (DbConnectionClosedException ignored) { + LOGGER.warn("Attempted to insert ["+this.dtoClass.getSimpleName()+"] with primary key ["+(dto != null ? dto.getPrimaryKeyString() : "NULL")+"] on closed repo ["+this.connectionString+"]."); } catch (SQLException e) { @@ -155,8 +156,9 @@ public abstract class AbstractDhRepo { this.query(statement); } - catch (DbConnectionClosedException ignored) + catch (DbConnectionClosedException e) { + LOGGER.warn("Attempted to update ["+this.dtoClass.getSimpleName()+"] with primary key ["+(dto != null ? dto.getPrimaryKeyString() : "NULL")+"] on closed repo ["+this.connectionString+"]."); } catch (SQLException e) { @@ -236,12 +238,16 @@ public abstract class AbstractDhRepo // SQL exceptions generally only happen when something is wrong with // the database or the query and should cause the system to blow up to notify the developer - if (e.toString().equals("database connection closed")) + if (DbConnectionClosedException.IsClosedException(e)) + { throw new DbConnectionClosedException(e); - - String message = "Unexpected Query error: ["+e.getMessage()+"], for prepared statement: ["+statement+"]."; - LOGGER.error(message); - throw new RuntimeException(message, e); + } + else + { + String message = "Unexpected Query error: [" + e.getMessage() + "], for prepared statement: [" + statement + "]."; + LOGGER.error(message); + throw new RuntimeException(message, e); + } } } /** note: this can only handle 1 command at a time */ @@ -263,12 +269,16 @@ public abstract class AbstractDhRepo // SQL exceptions generally only happen when something is wrong with // the database or the query and should cause the system to blow up to notify the developer - if (e.toString().equals("database connection closed")) + if (DbConnectionClosedException.IsClosedException(e)) + { throw new DbConnectionClosedException(e); - - String message = "Unexpected Query error: ["+e.getMessage()+"], for script: ["+sql+"]."; - LOGGER.error(message); - throw new RuntimeException(message, e); + } + else + { + String message = "Unexpected Query error: [" + e.getMessage() + "], for script: [" + sql + "]."; + LOGGER.error(message); + throw new RuntimeException(message, e); + } } } private List> parseQueryResult(ResultSet resultSet, boolean resultSetPresent) throws SQLException @@ -291,7 +301,7 @@ public abstract class AbstractDhRepo } - public PreparedStatement createPreparedStatement(String sql) + public PreparedStatement createPreparedStatement(String sql) throws DbConnectionClosedException { try { @@ -301,9 +311,19 @@ public abstract class AbstractDhRepo } catch(SQLException e) { - // SQL exceptions generally only happen when something is wrong with - // the database or the query and should cause the system to blow up to notify the developer - throw new RuntimeException(e); + if (DbConnectionClosedException.IsClosedException(e)) + { + throw new DbConnectionClosedException(e); + } + else + { + // SQL exceptions generally only happen when something is wrong with + // the database or the query and should cause the system to blow up to notify the developer + + String message = "Unexpected error: [" + e.getMessage() + "], preparing statement: [" + sql + "]."; + LOGGER.error(message); + throw new RuntimeException(message, e); + } } } @@ -339,7 +359,7 @@ public abstract class AbstractDhRepo { if(this.connection != null) { - LOGGER.debug("Closing database connection ["+this.connectionString+"]"); + LOGGER.info("Closing database connection ["+this.connectionString+"]"); CONNECTIONS_BY_CONNECTION_STRING.remove(this.connectionString); this.connection.close(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/sql/DbConnectionClosedException.java b/core/src/main/java/com/seibel/distanthorizons/core/sql/DbConnectionClosedException.java index 4c9dd400a..5f37e4213 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/sql/DbConnectionClosedException.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/sql/DbConnectionClosedException.java @@ -1,20 +1,21 @@ package com.seibel.distanthorizons.core.sql; -public class DbConnectionClosedException extends Exception +import java.sql.SQLException; + +/** + * Used to simplify handling when a database has been closed + * since Java doesn't have a specific exception to handle closed databases + */ +public class DbConnectionClosedException extends SQLException { - public DbConnectionClosedException() { - super("The database connection is closed."); - } + public DbConnectionClosedException() { super("The database connection is closed."); } + public DbConnectionClosedException(String message) { super(message); } + public DbConnectionClosedException(String message, Throwable cause) { super(message, cause); } + public DbConnectionClosedException(Throwable cause) { super(cause); } - public DbConnectionClosedException(String message) { - super(message); - } - public DbConnectionClosedException(String message, Throwable cause) { - super(message, cause); - } + // helper methods // + + public static boolean IsClosedException(SQLException e) { return e.getMessage().toLowerCase().contains("connection closed"); } - public DbConnectionClosedException(Throwable cause) { - super(cause); - } }