Skip to content

Commit

Permalink
Externalize some exception messages and states
Browse files Browse the repository at this point in the history
  • Loading branch information
mrotteveel committed Nov 27, 2024
1 parent e939d5b commit b07c28e
Show file tree
Hide file tree
Showing 41 changed files with 216 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.firebirdsql.gds.ng.jna.FbEmbeddedDatabaseFactory;

import java.sql.SQLException;
import java.sql.SQLNonTransientConnectionException;
import java.util.List;

public final class EmbeddedGDSFactoryPlugin extends BaseGDSFactoryPlugin {
Expand Down Expand Up @@ -72,10 +71,7 @@ public String getDefaultProtocol() {

@Override
public String getDatabasePath(String server, Integer port, String path) throws SQLException {
if (path == null) {
throw new SQLNonTransientConnectionException("Database name/path is required");
}

requirePath(path);
return path;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.firebirdsql.gds.ng.jna.FbClientDatabaseFactory;

import java.sql.SQLException;
import java.sql.SQLNonTransientConnectionException;
import java.util.List;

public final class NativeGDSFactoryPlugin extends BaseGDSFactoryPlugin {
Expand Down Expand Up @@ -77,10 +76,7 @@ public String getDefaultProtocol() {

@Override
public String getDatabasePath(String server, Integer port, String path) throws SQLException {
if (path == null) {
throw new SQLNonTransientConnectionException("Database name/path is required");
}

requirePath(path);
if (server == null) {
return path;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,18 @@
import com.sun.jna.ptr.ShortByReference;
import org.firebirdsql.gds.BlobParameterBuffer;
import org.firebirdsql.gds.ISCConstants;
import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ng.AbstractFbBlob;
import org.firebirdsql.gds.ng.FbBlob;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.gds.ng.LockCloseable;
import org.firebirdsql.gds.ng.listeners.DatabaseListener;
import org.firebirdsql.jaybird.util.ByteArrayHelper;
import org.firebirdsql.jdbc.SQLStateConstants;
import org.firebirdsql.jna.fbclient.FbClientLibrary;
import org.firebirdsql.jna.fbclient.ISC_STATUS;

import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.sql.SQLNonTransientException;

import static org.firebirdsql.gds.JaybirdErrorCodes.jb_blobGetSegmentNegative;
import static org.firebirdsql.gds.JaybirdErrorCodes.jb_blobPutSegmentEmpty;
Expand Down Expand Up @@ -203,9 +202,9 @@ protected int get(final byte[] b, final int off, final int len, final int minLen
validateBufferLength(b, off, len);
if (len == 0) return 0;
if (minLen <= 0 || minLen > len ) {
throw new SQLNonTransientException(
"Value out of range 0 < minLen <= %d, minLen was: %d".formatted(len, minLen),
SQLStateConstants.SQL_STATE_INVALID_STRING_LENGTH);
throw FbExceptionBuilder.forNonTransientException(JaybirdErrorCodes.jb_invalidStringLength)
.messageParameter("minLen", len, minLen)
.toSQLException();
}
checkDatabaseAttached();
checkTransactionActive();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,7 @@ public void attach() throws SQLException {
}

protected void attachOrCreate(final DatabaseParameterBuffer dpb, final boolean create) throws SQLException {
if (isAttached()) {
throw new SQLException("Already attached to a database");
}
requireNotAttached();
final byte[] dbName = getEncoding().encodeToCharset(connection.getAttachUrl());
final byte[] dpbArray = dpb.toBytesWithType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,8 @@ public void startServiceAction(ServiceRequestBuffer serviceRequestBuffer) throws
@Override
public void attach() throws SQLException {
try {
if (isAttached()) {
throw new SQLException("Already attached to a service");
}
try (LockCloseable ignored = withLock()) {
requireNotAttached();
try (var ignored = withLock()) {
attachImpl();
setAttached();
afterAttachActions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import java.lang.ref.Cleaner;
import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.sql.SQLNonTransientException;
import java.util.Arrays;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -143,13 +142,8 @@ public void prepare(String statementText) throws SQLException {
.toSQLException();
}
}
try (LockCloseable ignored = withLock()) {
checkTransactionActive(getTransaction());
final StatementState initialState = getState();
if (!isPrepareAllowed(initialState)) {
throw new SQLNonTransientException(String.format(
"Current statement state (%s) does not allow call to prepare", initialState));
}
try (var ignored = withLock()) {
final StatementState initialState = checkPrepareAllowed();
resetAll();

final JnaDatabase db = getDatabase();
Expand Down
4 changes: 2 additions & 2 deletions src/jna-test/org/firebirdsql/gds/ng/jna/JnaDatabaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void doubleAttach() throws Exception {

SQLException exception = assertThrows(SQLException.class, db::attach,
"Second attach should throw exception");
assertThat(exception, message(equalTo("Already attached to a database")));
assertThat(exception, message(startsWith("Already attached to a database")));
}
}

Expand Down Expand Up @@ -266,7 +266,7 @@ void testExecuteImmediate_createDatabase() throws Exception {
@Test
public void testOdsVersionInformation() throws Exception {
usesDatabase.createDefaultDatabase();
try (JnaDatabase db = factory.connect(connectionInfo);) {
try (JnaDatabase db = factory.connect(connectionInfo)) {
db.attach();

OdsVersion expectedOds = getDefaultSupportInfo().getDefaultOdsVersion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void doubleAttach() throws Exception {
//Second attach should throw exception
SQLException exception = assertThrows(SQLException.class, service::attach,
"Second attach should throw exception");
assertThat(exception, message(equalTo("Already attached to a service")));
assertThat(exception, message(startsWith("Already attached to a service")));
}
}

Expand Down
27 changes: 15 additions & 12 deletions src/main/org/firebirdsql/ds/FBPooledConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLNonTransientConnectionException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.Lock;
Expand All @@ -31,11 +30,12 @@
import javax.sql.PooledConnection;
import javax.sql.StatementEventListener;

import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.gds.ng.LockCloseable;
import org.firebirdsql.jaybird.util.SQLExceptionChainBuilder;
import org.firebirdsql.jaybird.xca.FatalErrorHelper;
import org.firebirdsql.jdbc.FirebirdConnection;
import org.firebirdsql.jdbc.SQLStateConstants;

/**
* PooledConnection implementation for {@link FBConnectionPoolDataSource}
Expand Down Expand Up @@ -63,28 +63,31 @@ LockCloseable withLock() {

@Override
public Connection getConnection() throws SQLException {
try (LockCloseable ignored = withLock()) {
if (connection == null) {
var ex = new SQLNonTransientConnectionException("The PooledConnection has been closed",
SQLStateConstants.SQL_STATE_CONNECTION_CLOSED);
fireFatalConnectionError(ex);
throw ex;
}
try (var ignored = withLock()) {
try {
Connection connection = requireConnection();
if (handler != null) {
handler.close();
}
resetConnection(connection);
handler = createConnectionHandler(connection);

return handler.getProxy();
} catch (SQLException ex) {
fireFatalConnectionError(ex);
throw ex;
}
handler = createConnectionHandler(connection);

return handler.getProxy();
}
}

private Connection requireConnection() throws SQLException {
Connection connection = this.connection;
if (connection != null) return connection;
throw FbExceptionBuilder
.forNonTransientConnectionException(JaybirdErrorCodes.jb_pooledConnectionClosed)
.toSQLException();
}

void resetConnection(Connection connection) throws SQLException {
connection.setAutoCommit(true);
if (connection.isWrapperFor(FirebirdConnection.class)) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/org/firebirdsql/ds/FBSimpleDataSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
*/
package org.firebirdsql.ds;

import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.TransactionParameterBuffer;
import org.firebirdsql.gds.impl.GDSFactory;
import org.firebirdsql.gds.impl.GDSType;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.jaybird.props.def.ConnectionProperty;
import org.firebirdsql.jaybird.xca.FBManagedConnectionFactory;
import org.firebirdsql.jdbc.FBDataSource;
Expand Down Expand Up @@ -243,7 +245,9 @@ public boolean isWrapperFor(Class<?> iface) throws SQLException {
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
if (!isWrapperFor(iface)) {
throw new SQLException("Unable to unwrap to class " + iface.getName());
throw FbExceptionBuilder.forException(JaybirdErrorCodes.jb_unableToUnwrap)
.messageParameter(iface != null ? iface.getName() : "(null)")
.toSQLException();
}

return iface.cast(this);
Expand Down
8 changes: 4 additions & 4 deletions src/main/org/firebirdsql/ds/FBXAConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
import java.lang.ref.WeakReference;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLNonTransientConnectionException;

import javax.sql.XAConnection;
import javax.transaction.xa.XAResource;

import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.jaybird.xca.FBManagedConnection;
import org.firebirdsql.jdbc.FBConnection;
import org.firebirdsql.jdbc.SQLStateConstants;

/**
* XAConnection implementation for {@link FBXADataSource}
Expand Down Expand Up @@ -69,8 +69,8 @@ boolean inDistributedTransaction() throws SQLException {
private FBManagedConnection getManagedConnection() throws SQLException {
FBManagedConnection managedConnection = mc.get();
if (managedConnection == null) {
throw new SQLNonTransientConnectionException("Managed Connection is null, connection unavailable",
SQLStateConstants.SQL_STATE_CONNECTION_CLOSED);
throw FbExceptionBuilder.forNonTransientConnectionException(JaybirdErrorCodes.jb_noManagedConnection)
.toSQLException();
}
return managedConnection;
}
Expand Down
13 changes: 6 additions & 7 deletions src/main/org/firebirdsql/ds/PooledConnectionHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,24 @@
*/
package org.firebirdsql.ds;

import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.gds.ng.LockCloseable;
import org.firebirdsql.jaybird.util.SQLExceptionChainBuilder;
import org.firebirdsql.jdbc.FirebirdConnection;
import org.firebirdsql.jdbc.SQLStateConstants;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLNonTransientConnectionException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static org.firebirdsql.gds.JaybirdErrorCodes.jb_logicalConnectionClosed;
import static org.firebirdsql.gds.JaybirdErrorCodes.jb_logicalConnectionForciblyClosed;
import static org.firebirdsql.jaybird.util.ReflectionHelper.findMethod;
import static org.firebirdsql.jaybird.util.ReflectionHelper.getAllInterfaces;

Expand All @@ -50,9 +51,6 @@
*/
sealed class PooledConnectionHandler implements InvocationHandler permits XAConnectionHandler {

static final String CLOSED_MESSAGE = "Logical connection already closed";
static final String FORCIBLY_CLOSED_MESSAGE =
"Logical connection was forcibly closed by the connection pool";
private final FBPooledConnection owner;
@SuppressWarnings("java:S3077")
volatile Connection connection;
Expand Down Expand Up @@ -95,8 +93,9 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
throw e.getTargetException();
}
} else if (isClosed() && !method.equals(CONNECTION_CLOSE)) {
String message = forcedClose ? FORCIBLY_CLOSED_MESSAGE : CLOSED_MESSAGE;
throw new SQLNonTransientConnectionException(message, SQLStateConstants.SQL_STATE_CONNECTION_CLOSED);
throw FbExceptionBuilder.forNonTransientConnectionException(
forcedClose ? jb_logicalConnectionForciblyClosed : jb_logicalConnectionClosed)
.toSQLException();
}

try {
Expand Down
7 changes: 3 additions & 4 deletions src/main/org/firebirdsql/ds/StatementHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.SQLException;
import java.sql.SQLNonTransientException;
import java.sql.Statement;

import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.jdbc.FirebirdStatement;
import org.firebirdsql.jdbc.SQLStateConstants;

import static org.firebirdsql.jaybird.util.ReflectionHelper.*;

Expand Down Expand Up @@ -85,8 +85,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
} else if (method.equals(STATEMENT_IS_CLOSED) || method.equals(FIREBIRD_STATEMENT_IS_CLOSED)) {
return isClosed();
} else if (isClosed() && !method.equals(STATEMENT_CLOSE)) {
throw new SQLNonTransientException("Statement is already closed",
SQLStateConstants.SQL_STATE_INVALID_STATEMENT_ID);
throw FbExceptionBuilder.forNonTransientException(JaybirdErrorCodes.jb_stmtClosed).toSQLException();
}

// Methods of statement and subinterfaces
Expand Down
11 changes: 11 additions & 0 deletions src/main/org/firebirdsql/gds/JaybirdErrorCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ public interface JaybirdErrorCodes {
int jb_eventHandleNotInitialized = 337248326;
int jb_attemptToDestroyManagedConnectionActiveTx = 337248327;
int jb_cannotInstantiateConnection = 337248328;
int jb_databasePathRequired = 337248329;
int jb_invalidStringLength = 337248330;
int jb_alreadyAttached = 337248331;
int jb_prepareNotAllowedByState = 337248332;
int jb_noActiveTransaction = 337248333;
int jb_pooledConnectionClosed = 337248334;
int jb_noManagedConnection = 337248335;
int jb_logicalConnectionClosed = 337248336;
int jb_logicalConnectionForciblyClosed = 337248337;
int jb_unableToUnwrap = 337248338;
int jb_resultSetClosed = 337248339;

@SuppressWarnings("unused")
int jb_range_end = 337264639;
Expand Down
22 changes: 19 additions & 3 deletions src/main/org/firebirdsql/gds/impl/BaseGDSFactoryPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package org.firebirdsql.gds.impl;

import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.jdbc.FBConnection;

import java.sql.SQLException;
Expand Down Expand Up @@ -55,11 +57,25 @@ public String getDatabasePath(String jdbcUrl) throws SQLException {
throw new SQLNonTransientConnectionException("Incorrect JDBC protocol handling: " + jdbcUrl);
}

@Override
public String getDatabasePath(String server, Integer port, String path) throws SQLException {
/**
* Checks if {@code path} is not {@code null}.
*
* @param path
* path to check
* @throws SQLException
* if {@code path} is {@code null}
* @since 6
*/
protected static void requirePath(String path) throws SQLException {
if (path == null) {
throw new SQLNonTransientConnectionException("Database name/path is required");
throw FbExceptionBuilder.forNonTransientConnectionException(JaybirdErrorCodes.jb_databasePathRequired)
.toSQLException();
}
}

@Override
public String getDatabasePath(String server, Integer port, String path) throws SQLException {
requirePath(path);

if (server == null) {
return path;
Expand Down
Loading

0 comments on commit b07c28e

Please sign in to comment.