From 5df9882859ced5d746a59aaf3e808dd18f4ff9e3 Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Fri, 1 Dec 2023 09:29:20 +0000 Subject: [PATCH 1/4] Redesign jdbc exception to use standart classes --- .../ydb/jdbc/exception/ExceptionFactory.java | 36 +++++++++++++++++ .../YdbConditionallyRetryableException.java | 18 ++++++--- .../exception/YdbConfigurationException.java | 15 ------- .../jdbc/exception/YdbExecutionException.java | 19 --------- .../exception/YdbNonRetryableException.java | 11 ----- .../YdbResultTruncatedException.java | 9 ----- .../jdbc/exception/YdbRetryableException.java | 17 ++++++-- .../jdbc/exception/YdbRuntimeException.java | 13 ------ .../ydb/jdbc/exception/YdbSQLException.java | 21 ++++++++++ .../jdbc/exception/YdbStatusException.java | 40 ------------------- 10 files changed, 83 insertions(+), 116 deletions(-) create mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java delete mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConfigurationException.java delete mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbExecutionException.java delete mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbNonRetryableException.java delete mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbResultTruncatedException.java delete mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRuntimeException.java create mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbSQLException.java delete mode 100644 jdbc/src/main/java/tech/ydb/jdbc/exception/YdbStatusException.java diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java new file mode 100644 index 0000000..57a19e2 --- /dev/null +++ b/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java @@ -0,0 +1,36 @@ +package tech.ydb.jdbc.exception; + +import java.sql.SQLException; + +import tech.ydb.core.StatusCode; +import tech.ydb.core.UnexpectedResultException; + +/** + * + * @author Aleksandr Gorshenin + */ +public class ExceptionFactory { + static String getSQLState(StatusCode status) { + // TODO: Add SQLSTATE message with order with https://en.wikipedia.org/wiki/SQLSTATE + return null; + } + + static int getVendorCode(StatusCode code) { + return code.getCode(); + } + + public static SQLException createException(UnexpectedResultException cause) { + StatusCode code = cause.getStatus().getCode(); + String sqlState = getSQLState(code); + int vendorCode = getVendorCode(code); + + if (code.isRetryable(false)) { + return new YdbRetryableException(cause.getMessage(), sqlState, vendorCode, cause); + } + if (code.isRetryable(true)) { + return new YdbConditionallyRetryableException(cause.getMessage(), sqlState, vendorCode, cause); + } + + return new YdbSQLException(cause.getMessage(), sqlState, vendorCode, cause); + } +} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConditionallyRetryableException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConditionallyRetryableException.java index 599e60d..2a45d0a 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConditionallyRetryableException.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConditionallyRetryableException.java @@ -1,12 +1,20 @@ package tech.ydb.jdbc.exception; +import java.sql.SQLTransientException; + import tech.ydb.core.Status; +import tech.ydb.core.UnexpectedResultException; + +public class YdbConditionallyRetryableException extends SQLTransientException { + private static final long serialVersionUID = 2155728765762467203L; + private final Status status; -// Treat this as non retryable exception by nature, i.e. need to handle in consciously -public class YdbConditionallyRetryableException extends YdbNonRetryableException { - private static final long serialVersionUID = -2371144941971339449L; + YdbConditionallyRetryableException(String message, String sqlState, int code, UnexpectedResultException cause) { + super(message, sqlState, code, cause); + this.status = cause.getStatus(); + } - YdbConditionallyRetryableException(String message, String sqlState, Status status) { - super(message, sqlState, status); + public Status getStatus() { + return status; } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConfigurationException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConfigurationException.java deleted file mode 100644 index 2812b6f..0000000 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbConfigurationException.java +++ /dev/null @@ -1,15 +0,0 @@ -package tech.ydb.jdbc.exception; - -import java.sql.SQLException; - -public class YdbConfigurationException extends SQLException { - private static final long serialVersionUID = -9023124863392765984L; - - public YdbConfigurationException(String message) { - super(message); - } - - public YdbConfigurationException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbExecutionException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbExecutionException.java deleted file mode 100644 index 9da7bad..0000000 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbExecutionException.java +++ /dev/null @@ -1,19 +0,0 @@ -package tech.ydb.jdbc.exception; - -import java.sql.SQLException; - -public class YdbExecutionException extends SQLException { - private static final long serialVersionUID = -9189855688894485591L; - - public YdbExecutionException(String reason) { - super(reason); - } - - public YdbExecutionException(String reason, Throwable cause) { - super(reason, cause); - } - - public YdbExecutionException(String reason, String SQLState, int vendorCode) { - super(reason, SQLState, vendorCode); - } -} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbNonRetryableException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbNonRetryableException.java deleted file mode 100644 index 8044984..0000000 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbNonRetryableException.java +++ /dev/null @@ -1,11 +0,0 @@ -package tech.ydb.jdbc.exception; - -import tech.ydb.core.Status; - -public class YdbNonRetryableException extends YdbStatusException { - private static final long serialVersionUID = 687247673341671225L; - - YdbNonRetryableException(String message, String sqlState, Status status) { - super(message, sqlState, status); - } -} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbResultTruncatedException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbResultTruncatedException.java deleted file mode 100644 index 092192c..0000000 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbResultTruncatedException.java +++ /dev/null @@ -1,9 +0,0 @@ -package tech.ydb.jdbc.exception; - -public class YdbResultTruncatedException extends YdbExecutionException { - private static final long serialVersionUID = -1887300249465409232L; - - public YdbResultTruncatedException(String reason) { - super(reason); - } -} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRetryableException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRetryableException.java index ed1b922..ae1c384 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRetryableException.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRetryableException.java @@ -1,11 +1,20 @@ package tech.ydb.jdbc.exception; +import java.sql.SQLRecoverableException; + import tech.ydb.core.Status; +import tech.ydb.core.UnexpectedResultException; + +public class YdbRetryableException extends SQLRecoverableException { + private static final long serialVersionUID = -7171306648623023924L; + private final Status status; -public class YdbRetryableException extends YdbStatusException { - private static final long serialVersionUID = 2082287790625648960L; + YdbRetryableException(String message, String sqlState, int code, UnexpectedResultException cause) { + super(message, sqlState, code, cause); + this.status = cause.getStatus(); + } - YdbRetryableException(String message, String sqlState, Status status) { - super(message, sqlState, status); + public Status getStatus() { + return status; } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRuntimeException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRuntimeException.java deleted file mode 100644 index 0feb754..0000000 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbRuntimeException.java +++ /dev/null @@ -1,13 +0,0 @@ -package tech.ydb.jdbc.exception; - -public class YdbRuntimeException extends RuntimeException { - private static final long serialVersionUID = 7195253335276429670L; - - public YdbRuntimeException(String message) { - super(message); - } - - public YdbRuntimeException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbSQLException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbSQLException.java new file mode 100644 index 0000000..c8af441 --- /dev/null +++ b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbSQLException.java @@ -0,0 +1,21 @@ +package tech.ydb.jdbc.exception; + +import java.sql.SQLException; + +import tech.ydb.core.Status; +import tech.ydb.core.UnexpectedResultException; + +public class YdbSQLException extends SQLException { + private static final long serialVersionUID = 6204553083196091739L; + + private final Status status; + + YdbSQLException(String message, String sqlState, int code, UnexpectedResultException cause) { + super(message, sqlState, code, cause); + this.status = cause.getStatus(); + } + + public Status getStatus() { + return status; + } +} diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbStatusException.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbStatusException.java deleted file mode 100644 index 4edb87b..0000000 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/YdbStatusException.java +++ /dev/null @@ -1,40 +0,0 @@ -package tech.ydb.jdbc.exception; - -import tech.ydb.core.Status; -import tech.ydb.core.StatusCode; - -public class YdbStatusException extends YdbExecutionException { - private static final long serialVersionUID = -8082086858749679589L; - - private final Status status; - - protected YdbStatusException(String message, String state, Status status) { - super(message, state, status.getCode().getCode()); - this.status = status; - } - - public Status getStatus() { - return status; - } - - public static YdbStatusException newException(String message, Status status) { - if (status.getCode().isRetryable(false)) { - String sqlState = "Retryable[" + status.toString() + "]"; - return new YdbRetryableException(message, sqlState, status); - } - - if (status.getCode().isRetryable(true)) { - String sqlState = "ConditionallyRetryable[" + status.toString() + "]"; - return new YdbConditionallyRetryableException(message, sqlState, status); - } - - String sqlState = "NonRetryable[" + status.toString() + "]"; - return new YdbNonRetryableException(message, sqlState, status); - } - - public static YdbStatusException newBadRequest(String message) { - Status status = Status.of(StatusCode.BAD_REQUEST); - String sqlState = "NonRetryable[" + status.toString() + "]"; - return new YdbNonRetryableException(message, sqlState, status); - } -} From d554e84c1bde0e1c2ff035ffcac3c964917e71f1 Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Fri, 1 Dec 2023 09:31:02 +0000 Subject: [PATCH 2/4] Update usage of exceptions --- .../tech/ydb/jdbc/common/MappingSetters.java | 5 ++-- .../tech/ydb/jdbc/context/YdbContext.java | 5 ++-- .../tech/ydb/jdbc/context/YdbExecutor.java | 28 +++++++------------ .../tech/ydb/jdbc/impl/BaseYdbStatement.java | 3 +- .../tech/ydb/jdbc/impl/YdbConnectionImpl.java | 6 ++-- .../jdbc/impl/YdbDatabaseMetaDataImpl.java | 5 ++-- .../tech/ydb/jdbc/impl/YdbJdbcParams.java | 4 +-- .../jdbc/impl/YdbPreparedStatementImpl.java | 6 ++-- .../java/tech/ydb/jdbc/impl/YdbTypesImpl.java | 4 +-- .../ydb/jdbc/impl/params/BatchedParams.java | 4 +-- .../ydb/jdbc/impl/params/PreparedParams.java | 16 +++++++++-- .../java/tech/ydb/jdbc/query/YdbQuery.java | 4 +-- .../tech/ydb/jdbc/query/YdbQueryBuilder.java | 7 +++-- .../ydb/jdbc/settings/PropertyConverter.java | 5 ++-- .../tech/ydb/jdbc/settings/YdbJdbcTools.java | 19 ++++++------- 15 files changed, 56 insertions(+), 65 deletions(-) diff --git a/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java b/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java index 206127f..3a3b152 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java @@ -22,7 +22,6 @@ import com.google.common.io.ByteStreams; import com.google.common.io.CharStreams; -import tech.ydb.jdbc.exception.YdbExecutionException; import tech.ydb.table.values.DecimalType; import tech.ydb.table.values.DecimalValue; import tech.ydb.table.values.ListType; @@ -461,7 +460,7 @@ static CharStream fromReader(Reader reader, long length) { return CharStreams.toString(reader); } } catch (IOException e) { - throw new YdbExecutionException(CANNOT_LOAD_DATA_FROM_READER + e.getMessage(), e); + throw new RuntimeException(CANNOT_LOAD_DATA_FROM_READER + e.getMessage(), e); } }; } @@ -480,7 +479,7 @@ static ByteStream fromInputStream(InputStream stream, long length) { return ByteStreams.toByteArray(stream); } } catch (IOException e) { - throw new YdbExecutionException(CANNOT_LOAD_DATA_FROM_IS + e.getMessage(), e); + throw new RuntimeException(CANNOT_LOAD_DATA_FROM_IS + e.getMessage(), e); } }; } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java index d0acbb5..640aac4 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java @@ -10,7 +10,6 @@ import tech.ydb.core.grpc.GrpcTransport; import tech.ydb.core.grpc.GrpcTransportBuilder; -import tech.ydb.jdbc.exception.YdbConfigurationException; import tech.ydb.jdbc.query.YdbQueryOptions; import tech.ydb.jdbc.settings.ParsedProperty; import tech.ydb.jdbc.settings.YdbClientProperties; @@ -132,8 +131,8 @@ public static YdbContext createContext(YdbConfig config) throws SQLException { boolean autoResize = buildTableClient(tableClient, clientProps); return new YdbContext(config, grpcTransport, tableClient.build(), autoResize); - } catch (Exception ex) { - throw new YdbConfigurationException("Cannot connect to YDB: " + ex.getMessage(), ex); + } catch (RuntimeException ex) { + throw new SQLException("Cannot connect to YDB: " + ex.getMessage(), ex); } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java index d0784ba..fd4e454 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java @@ -16,8 +16,8 @@ import tech.ydb.core.Issue; import tech.ydb.core.Result; import tech.ydb.core.Status; -import tech.ydb.jdbc.exception.YdbExecutionException; -import tech.ydb.jdbc.exception.YdbStatusException; +import tech.ydb.core.UnexpectedResultException; +import tech.ydb.jdbc.exception.ExceptionFactory; import tech.ydb.table.Session; /** @@ -62,7 +62,7 @@ public Session createSession(YdbContext ctx) throws SQLException { public void execute(String msg, Supplier> runnableSupplier) throws SQLException { if (!isDebug) { - simpleExecute(runnableSupplier); + simpleExecute(msg, runnableSupplier); return; } @@ -70,7 +70,7 @@ public void execute(String msg, Supplier> runnableSupp Stopwatch sw = Stopwatch.createStarted(); try { - simpleExecute(runnableSupplier); + simpleExecute(msg, runnableSupplier); logger.log(Level.FINEST, "[{0}] OK ", sw.stop()); } catch (SQLException | RuntimeException ex) { logger.log(Level.FINE, "[{0}] {1} ", new Object[] { sw.stop(), ex.getMessage() }); @@ -99,26 +99,18 @@ public T call(String msg, Supplier>> callSupplie private T simpleCall(Supplier>> supplier) throws SQLException { try { Result result = supplier.get().join(); - validate(result.getStatus().toString(), result.getStatus()); + issues.addAll(Arrays.asList(result.getStatus().getIssues())); return result.getValue(); - } catch (RuntimeException ex) { - throw new YdbExecutionException(ex.getMessage(), ex); + } catch (UnexpectedResultException ex) { + throw ExceptionFactory.createException(ex); } } - private void simpleExecute(Supplier> supplier) throws SQLException { - try { - Status status = supplier.get().join(); - validate(status.toString(), status); - } catch (RuntimeException ex) { - throw new YdbExecutionException(ex.getMessage(), ex); - } - } - - private void validate(String message, Status status) throws SQLException { + private void simpleExecute(String msg, Supplier> supplier) throws SQLException { + Status status = supplier.get().join(); issues.addAll(Arrays.asList(status.getIssues())); if (!status.isSuccess()) { - throw YdbStatusException.newException(message, status); + throw ExceptionFactory.createException(new UnexpectedResultException(msg, status)); } } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java index 3ed75ad..1d35d22 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java @@ -18,7 +18,6 @@ import tech.ydb.jdbc.YdbStatement; import tech.ydb.jdbc.common.FixedResultSetFactory; import tech.ydb.jdbc.context.YdbExecutor; -import tech.ydb.jdbc.exception.YdbResultTruncatedException; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.jdbc.query.YdbQueryOptions; import tech.ydb.jdbc.settings.YdbOperationProperties; @@ -213,7 +212,7 @@ protected ResultState executeDataQuery(YdbQuery query, Params params) throws SQL ResultSetReader rs = result.getResultSet(idx); if (failOnTruncatedResult && rs.isTruncated()) { String msg = String.format(YdbConst.RESULT_IS_TRUNCATED, idx, rs.getRowCount()); - throw new YdbResultTruncatedException(msg); + throw new SQLException(msg); } list.add(new YdbResultSetImpl(this, rs)); } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java index 4e735c6..68b295b 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java @@ -36,7 +36,6 @@ import tech.ydb.jdbc.context.YdbContext; import tech.ydb.jdbc.context.YdbExecutor; import tech.ydb.jdbc.context.YdbTxState; -import tech.ydb.jdbc.exception.YdbExecutionException; import tech.ydb.jdbc.query.QueryType; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.jdbc.settings.FakeTxMode; @@ -270,7 +269,7 @@ public void executeSchemeQuery(YdbQuery query, YdbExecutor executor) throws SQLE break; case ERROR: default: - throw new YdbExecutionException(YdbConst.SCHEME_QUERY_INSIDE_TRANSACTION); + throw new SQLException(YdbConst.SCHEME_QUERY_INSIDE_TRANSACTION); } } @@ -317,8 +316,7 @@ public ResultSetReader executeScanQuery(YdbQuery query, YdbExecutor executor, Pa break; case ERROR: default: - throw new YdbExecutionException(YdbConst.SCAN_QUERY_INSIDE_TRANSACTION); - + throw new SQLException(YdbConst.SCAN_QUERY_INSIDE_TRANSACTION); } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java index cb0474b..82ef0c7 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java @@ -30,7 +30,6 @@ import tech.ydb.jdbc.common.FixedResultSetFactory; import tech.ydb.jdbc.common.YdbFunctions; import tech.ydb.jdbc.context.YdbExecutor; -import tech.ydb.jdbc.exception.YdbStatusException; import tech.ydb.proto.scheme.SchemeOperationProtos; import tech.ydb.scheme.SchemeClient; import tech.ydb.scheme.description.ListDirectoryResult; @@ -1354,8 +1353,8 @@ private TableDescription describeTable(String table) throws SQLException { return executor.call("Describe table " + table, () -> session.describeTable(databaseWithSuffix + table, settings) ); - } catch (YdbStatusException ex) { - if (ex.getStatus().getCode() != StatusCode.SCHEME_ERROR) { // ignore scheme errors like path not found + } catch (SQLException ex) { + if (ex.getErrorCode() != StatusCode.SCHEME_ERROR.getCode()) {// ignore scheme errors like path not found throw ex; } LOGGER.log(Level.WARNING, "Cannot describe table {0} -> {1}", diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbJdbcParams.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbJdbcParams.java index 79264e7..b6881b5 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbJdbcParams.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbJdbcParams.java @@ -1,5 +1,6 @@ package tech.ydb.jdbc.impl; +import java.sql.SQLDataException; import java.sql.SQLException; import java.util.List; @@ -9,7 +10,6 @@ import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.YdbPrepareMode; import tech.ydb.jdbc.common.TypeDescription; -import tech.ydb.jdbc.exception.YdbExecutionException; import tech.ydb.jdbc.impl.params.BatchedParams; import tech.ydb.jdbc.impl.params.InMemoryParams; import tech.ydb.jdbc.impl.params.PreparedParams; @@ -61,7 +61,7 @@ static YdbJdbcParams create(YdbConnectionImpl connection, YdbQuery query, YdbPre } if (requireBatch) { - throw new YdbExecutionException(YdbConst.STATEMENT_IS_NOT_A_BATCH + query.originSQL()); + throw new SQLDataException(YdbConst.STATEMENT_IS_NOT_A_BATCH + query.originSQL()); } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java index c94bbd2..3ec05bb 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbPreparedStatementImpl.java @@ -12,6 +12,7 @@ import java.sql.Ref; import java.sql.ResultSetMetaData; import java.sql.RowId; +import java.sql.SQLDataException; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLXML; @@ -30,7 +31,6 @@ import tech.ydb.jdbc.YdbResultSet; import tech.ydb.jdbc.YdbTypes; import tech.ydb.jdbc.common.MappingSetters; -import tech.ydb.jdbc.exception.YdbExecutionException; import tech.ydb.jdbc.query.YdbQuery; import tech.ydb.table.query.Params; import tech.ydb.table.values.Type; @@ -193,7 +193,7 @@ public void setObject(int parameterIndex, Object value, Type type) throws SQLExc @Override public void setObject(String parameterName, Object x) throws SQLException { if (x == null) { - throw new YdbExecutionException(String.format(YdbConst.UNABLE_TO_SET_NULL_OBJECT)); + throw new SQLDataException(YdbConst.UNABLE_TO_SET_NULL_OBJECT); } params.setParam(parameterName, x, ydbType(x.getClass())); } @@ -201,7 +201,7 @@ public void setObject(String parameterName, Object x) throws SQLException { @Override public void setObject(int parameterIndex, Object x) throws SQLException { if (x == null) { - throw new YdbExecutionException(String.format(YdbConst.UNABLE_TO_SET_NULL_OBJECT)); + throw new SQLDataException(YdbConst.UNABLE_TO_SET_NULL_OBJECT); } params.setParam(parameterIndex, x, ydbType(x.getClass())); } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java index 7a8585d..440e4bf 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java @@ -25,7 +25,6 @@ import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.YdbTypes; -import tech.ydb.jdbc.exception.YdbRuntimeException; import tech.ydb.table.values.DecimalValue; import tech.ydb.table.values.PrimitiveType; import tech.ydb.table.values.Type; @@ -210,8 +209,7 @@ public int unwrapYdbJdbcType(int sqlType) { Integer value = sqlTypeByPrimitiveNumId.get(type); if (value == null) { - throw new YdbRuntimeException("Internal error. Unsupported YDB type: " + idType + - " as " + type); + throw new RuntimeException("Internal error. Unsupported YDB type: " + idType + " as " + type); } return value; } else { diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/params/BatchedParams.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/params/BatchedParams.java index 874be7d..14c2717 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/params/BatchedParams.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/params/BatchedParams.java @@ -1,6 +1,7 @@ package tech.ydb.jdbc.impl.params; +import java.sql.SQLDataException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; @@ -14,7 +15,6 @@ import tech.ydb.jdbc.YdbConst; import tech.ydb.jdbc.common.TypeDescription; -import tech.ydb.jdbc.exception.YdbStatusException; import tech.ydb.jdbc.impl.YdbJdbcParams; import tech.ydb.table.query.Params; import tech.ydb.table.values.ListType; @@ -119,7 +119,7 @@ private StructValue validatedCurrentStruct() throws SQLException { continue; } - throw YdbStatusException.newBadRequest(YdbConst.MISSING_VALUE_FOR_PARAMETER + prm.displayName()); + throw new SQLDataException(YdbConst.MISSING_VALUE_FOR_PARAMETER + prm.displayName()); } return StructValue.of(currentValues); } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/params/PreparedParams.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/params/PreparedParams.java index d76239d..34b9008 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/params/PreparedParams.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/params/PreparedParams.java @@ -1,6 +1,7 @@ package tech.ydb.jdbc.impl.params; +import java.sql.SQLDataException; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; @@ -94,7 +95,7 @@ public void clearParameters() { } @Override - public void addBatch() { + public void addBatch() throws SQLException { batchList.add(getCurrentParams()); clearParameters(); } @@ -114,14 +115,23 @@ public int batchSize() { return batchList.size(); } + private Params validateParams(Map> values) throws SQLException { + for (String key: this.params.keySet()) { + if (!values.containsKey(key)) { + throw new SQLDataException(YdbConst.MISSING_VALUE_FOR_PARAMETER + key); + } + } + return Params.copyOf(values); + } + @Override public List getBatchParams() { return batchList; } @Override - public Params getCurrentParams() { - return Params.copyOf(paramValues); + public Params getCurrentParams() throws SQLException { + return validateParams(paramValues); } @Override diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQuery.java b/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQuery.java index 361ec70..8705ad0 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQuery.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQuery.java @@ -2,12 +2,12 @@ +import java.sql.SQLDataException; import java.sql.SQLException; import java.util.List; import java.util.Map; import tech.ydb.jdbc.YdbConst; -import tech.ydb.jdbc.exception.YdbStatusException; import tech.ydb.table.query.Params; import tech.ydb.table.values.Value; @@ -51,7 +51,7 @@ public String getYqlQuery(Params params) throws SQLException { for (int idx = 0; idx < indexesArgsNames.size(); idx += 1) { String prm = indexesArgsNames.get(idx); if (!values.containsKey(prm)) { - throw YdbStatusException.newBadRequest(YdbConst.MISSING_VALUE_FOR_PARAMETER + prm); + throw new SQLDataException(YdbConst.MISSING_VALUE_FOR_PARAMETER + prm); } if (opts.isDeclareJdbcParameters()) { diff --git a/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQueryBuilder.java b/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQueryBuilder.java index 7100bdd..96a24c0 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQueryBuilder.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/query/YdbQueryBuilder.java @@ -1,10 +1,11 @@ package tech.ydb.jdbc.query; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.List; import tech.ydb.jdbc.YdbConst; -import tech.ydb.jdbc.exception.YdbStatusException; /** * @@ -36,13 +37,13 @@ public String createNextArgName() { } } - public void setQueryType(QueryType type) throws YdbStatusException { + public void setQueryType(QueryType type) throws SQLException { if (forcedType != null) { return; } if (currentType != null && currentType != type) { - throw YdbStatusException.newBadRequest(YdbConst.MULTI_TYPES_IN_ONE_QUERY + currentType + ", " + type); + throw new SQLFeatureNotSupportedException(YdbConst.MULTI_TYPES_IN_ONE_QUERY + currentType + ", " + type); } this.currentType = type; } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/settings/PropertyConverter.java b/jdbc/src/main/java/tech/ydb/jdbc/settings/PropertyConverter.java index 44f5358..ccbe86d 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/settings/PropertyConverter.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/settings/PropertyConverter.java @@ -5,7 +5,6 @@ import java.time.format.DateTimeParseException; import java.util.Locale; -import tech.ydb.jdbc.exception.YdbConfigurationException; interface PropertyConverter { T convert(String value) throws SQLException; @@ -31,7 +30,7 @@ static PropertyConverter durationValue() { try { return Duration.parse(targetValue); } catch (DateTimeParseException e) { - throw new YdbConfigurationException("Unable to parse value [" + value + "] -> [" + + throw new RuntimeException("Unable to parse value [" + value + "] -> [" + targetValue + "] as Duration: " + e.getMessage(), e); } }; @@ -42,7 +41,7 @@ static PropertyConverter integerValue() { try { return Integer.valueOf(value); } catch (NumberFormatException e) { - throw new YdbConfigurationException("Unable to parse value [" + value + "] as Integer: " + + throw new RuntimeException("Unable to parse value [" + value + "] as Integer: " + e.getMessage(), e); } }; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbJdbcTools.java b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbJdbcTools.java index 80a9d4a..48515c5 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbJdbcTools.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/settings/YdbJdbcTools.java @@ -14,7 +14,6 @@ import tech.ydb.core.utils.URITools; import tech.ydb.jdbc.YdbConst; -import tech.ydb.jdbc.exception.YdbConfigurationException; /** @@ -31,7 +30,7 @@ public static boolean isYdb(String url) { public static YdbProperties from(String jdbcURL, Properties origProperties) throws SQLException { if (!isYdb(jdbcURL)) { String msg = "[" + jdbcURL + "] is not a YDB URL, must starts from " + YdbConst.JDBC_YDB_PREFIX; - throw new YdbConfigurationException(msg); + throw new SQLException(msg); } try { @@ -111,7 +110,7 @@ public static YdbProperties from(String jdbcURL, Properties origProperties) thro return new YdbProperties(ydbConnectionProps, ydbClientProperties, ydbOperationProperties); } catch (URISyntaxException | RuntimeException | UnsupportedEncodingException ex) { - throw new YdbConfigurationException(ex.getMessage(), ex); + throw new SQLException(ex.getMessage(), ex); } } @@ -130,16 +129,15 @@ public static YdbProperties from(String jdbcURL, Properties origProperties) thro String stringValue = (String) value; try { parsed = new ParsedProperty(stringValue, converter.convert(stringValue)); - } catch (SQLException e) { - throw new YdbConfigurationException("Unable to convert property " + - title + ": " + e.getMessage(), e); + } catch (RuntimeException e) { + throw new SQLException("Unable to convert property " + title + ": " + e.getMessage(), e); } } else { if (property.getType().isAssignableFrom(value.getClass())) { parsed = new ParsedProperty("", value); } else { - throw new SQLException("Invalid object property " + title + - ", must be " + property.getType() + ", got " + value.getClass()); + throw new SQLException("Invalid object property " + title +", must be " + property.getType() + + ", got " + value.getClass()); } } } else { @@ -147,9 +145,8 @@ public static YdbProperties from(String jdbcURL, Properties origProperties) thro if (stringValue != null) { try { parsed = new ParsedProperty(stringValue, converter.convert(stringValue)); - } catch (SQLException e) { - throw new YdbConfigurationException("Unable to convert property " + - title + ": " + e.getMessage(), e); + } catch (RuntimeException e) { + throw new SQLException("Unable to convert property " + title + ": " + e.getMessage(), e); } } else { parsed = null; From 0c6d34d1ade21ec7ba0f8a1d6d7c94b13c1897ef Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Fri, 1 Dec 2023 09:31:21 +0000 Subject: [PATCH 3/4] Update tests --- .../ydb/jdbc/YdbDriverProperitesTest.java | 17 ++++--- .../ydb/jdbc/YdbDriverStaticCredsTest.java | 2 +- .../ydb/jdbc/impl/YdbConnectionImplTest.java | 10 ++-- .../impl/YdbPreparedStatementImplTest.java | 9 ++-- .../jdbc/impl/YdbPreparedStatementTest.java | 2 +- ...StatementWithDataQueryBatchedImplTest.java | 4 +- ...reparedStatementWithDataQueryImplTest.java | 4 +- .../ydb/jdbc/impl/YdbStatementImplTest.java | 6 +-- .../ydb/jdbc/impl/helper/ExceptionAssert.java | 46 ++++++------------- 9 files changed, 44 insertions(+), 56 deletions(-) diff --git a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java index ca7a8a3..33f188e 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java @@ -29,7 +29,6 @@ import org.junit.jupiter.params.provider.MethodSource; import tech.ydb.auth.AuthProvider; -import tech.ydb.jdbc.exception.YdbConfigurationException; import tech.ydb.jdbc.impl.helper.ExceptionAssert; import tech.ydb.jdbc.settings.ParsedProperty; import tech.ydb.jdbc.settings.YdbClientProperty; @@ -51,7 +50,7 @@ public class YdbDriverProperitesTest { private YdbDriver driver; @BeforeAll - public static void beforeAll() throws YdbConfigurationException, IOException { + public static void beforeAll() throws SQLException, IOException { TOKEN_FILE = safeCreateFile(TOKEN_FROM_FILE); CERTIFICATE_FILE = safeCreateFile(CERTIFICATE_FROM_FILE); } @@ -222,7 +221,10 @@ public void getTokenAs(String token, String expectValue) throws SQLException { @MethodSource("unknownFiles") public void getTokenAsInvalid(String token, String expectException) { String url = "jdbc:ydb:ydb-demo.testhost.org:2135/test/db?token=" + token; - ExceptionAssert.ydbConfiguration(expectException, () -> YdbJdbcTools.from(url, new Properties())); + ExceptionAssert.sqlException( + "Unable to convert property token: " + expectException, + () -> YdbJdbcTools.from(url, new Properties()) + ); } @ParameterizedTest(name = "[{index}] {1}") @@ -246,14 +248,17 @@ public void getCaCertificateAs(String certificate, String expectValue) throws SQ public void getCaCertificateAsInvalid(String certificate, String expectException) { String url = "jdbc:ydb:ydb-demo.testhost.org:2135/test/db" + "?secureConnectionCertificate=" + certificate; - ExceptionAssert.ydbConfiguration(expectException, () -> YdbJdbcTools.from(url, new Properties())); + ExceptionAssert.sqlException( + "Unable to convert property secureConnectionCertificate: " + expectException, + () -> YdbJdbcTools.from(url, new Properties()) + ); } @ParameterizedTest @MethodSource("invalidDurationParams") public void invalidDuration(String param) { String url = "jdbc:ydb:ydb-demo.testhost.org:2135/test/db?" + param + "=1bc"; - ExceptionAssert.ydbConfiguration("Unable to convert property " + param + + ExceptionAssert.sqlException("Unable to convert property " + param + ": Unable to parse value [1bc] -> [PT1BC] as Duration: Text cannot be parsed to a Duration", () -> YdbJdbcTools.from(url, new Properties())); } @@ -262,7 +267,7 @@ public void invalidDuration(String param) { @MethodSource("invalidIntegerParams") public void invalidInteger(String param) { String url = "jdbc:ydb:ydb-demo.testhost.org:2135/test/db?" + param + "=1bc"; - ExceptionAssert.ydbConfiguration("Unable to convert property " + param + + ExceptionAssert.sqlException("Unable to convert property " + param + ": Unable to parse value [1bc] as Integer: For input string: \"1bc\"", () -> YdbJdbcTools.from(url, new Properties())); } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java index 3531d14..1e22e41 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java @@ -73,7 +73,7 @@ private void testConnection(ConnectionSupplier connectionSupplier) throws SQLExc } private void wrongConnection(ConnectionSupplier connectionSupplier) { - ExceptionAssert.ydbConfiguration("Cannot connect to YDB: gRPC error: (INTERNAL) get token exception: " + ExceptionAssert.sqlException("Cannot connect to YDB: gRPC error: (INTERNAL) get token exception: " + "Can't login, code: UNAUTHORIZED, issues: [#400020 Invalid password (S_FATAL)]", () -> testConnection(connectionSupplier)); } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java index 2d91d92..ea5cfeb 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java @@ -249,7 +249,7 @@ public void invalidSQLCancelTransaction() throws SQLException { String txId = getTxId(jdbc.connection()); Assertions.assertNotNull(txId); - ExceptionAssert.ydbNonRetryable("Column reference 'x' (S_ERROR)", () -> statement.execute("select 2 + x")); + ExceptionAssert.ydbException("Column reference 'x' (S_ERROR)", () -> statement.execute("select 2 + x")); statement.execute(SELECT_2_2); Assertions.assertNotNull(getTxId(jdbc.connection())); @@ -480,7 +480,7 @@ public void commitInvalidTx() throws SQLException { statement.execute(SIMPLE_UPSERT); statement.execute(SIMPLE_UPSERT); - ExceptionAssert.ydbNonRetryable("Member not found: key2. Did you mean key?", + ExceptionAssert.ydbException("Member not found: key2. Did you mean key?", () -> statement.executeQuery(QUERIES.wrongSelectSQL())); Assertions.assertNull(getTxId(jdbc.connection())); @@ -502,7 +502,7 @@ public void rollbackInvalidTx() throws SQLException { statement.execute(SIMPLE_UPSERT); - ExceptionAssert.ydbNonRetryable("Member not found: key2. Did you mean key?", + ExceptionAssert.ydbException("Member not found: key2. Did you mean key?", () -> statement.executeQuery(QUERIES.wrongSelectSQL())); Assertions.assertNull(getTxId(jdbc.connection())); @@ -746,7 +746,7 @@ public void testUnsupportedByStorageTableTypes(String type) throws SQLException String sql = "create table " + tableName + " (key Int32, payload " + type + ", primary key(key))"; try (Statement statement = jdbc.connection().createStatement()) { - ExceptionAssert.ydbNonRetryable("is not supported by storage", () -> statement.execute(sql)); + ExceptionAssert.ydbException("is not supported by storage", () -> statement.execute(sql)); } } @@ -762,7 +762,7 @@ public void testUnsupportedComplexTypes(String type) throws SQLException { String sql = "create table " + tableName + " (key Int32, payload " + type + ", primary key(key))"; try (Statement statement = jdbc.connection().createStatement()) { - ExceptionAssert.ydbNonRetryable("Invalid type for column: payload.", + ExceptionAssert.ydbException("Invalid type for column: payload.", () -> statement.execute(sql)); } } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementImplTest.java index 0346d12..3141948 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementImplTest.java @@ -143,7 +143,6 @@ public void unknownColumns(SqlQueries.YqlQuery mode) throws SQLException { statement.setInt("key", 1); ExceptionAssert.sqlException("Parameter not found: column0", () -> statement.setObject("column0", "value")); - statement.execute(); } } @@ -268,8 +267,8 @@ public void addAndClearBatch(SqlQueries.YqlQuery mode) throws SQLException { public void executeEmptyBatch(SqlQueries.YqlQuery mode) throws SQLException { String yql = TEST_TABLE.upsertOne(mode, "c_Text", "Text"); try (YdbPreparedStatement statement = jdbc.connection().unwrap(YdbConnection.class).prepareStatement(yql)) { - ExceptionAssert.ydbNonRetryable("Missing value for parameter", () -> statement.execute()); - ExceptionAssert.ydbNonRetryable("Missing value for parameter", () -> statement.executeUpdate()); + ExceptionAssert.sqlDataException("Missing value for parameter", () -> statement.execute()); + ExceptionAssert.sqlDataException("Missing value for parameter", () -> statement.executeUpdate()); statement.executeBatch(); } @@ -303,7 +302,7 @@ public void executeQueryBatchWithScanRead() throws SQLException { } } - ExceptionAssert.ydbResultTruncated("Result #0 was truncated to 1000 rows", () -> { + ExceptionAssert.sqlException("Result #0 was truncated to 1000 rows", () -> { // Result is truncated (and we catch that) try (PreparedStatement select = prepareSimpleSelect("c_Text")) { select.executeQuery(); @@ -427,7 +426,7 @@ public void executeScanQueryAsUpdate() throws SQLException { statement.setInt("key", 1); statement.setString("c_Text", "value-1"); - ExceptionAssert.ydbNonRetryable("Scan query should have a single result set", + ExceptionAssert.ydbException("Scan query should have a single result set", statement::executeScanQuery); } } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementTest.java index 2fe3cd8..f30c610 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementTest.java @@ -116,7 +116,7 @@ public void executeWithMissingParameter(SqlQueries.JdbcQuery query) throws SQLEx try (PreparedStatement statement = jdbc.connection().prepareStatement(sql)) { statement.setInt(1, 1); - ExceptionAssert.ydbNonRetryable("Missing value for parameter", statement::execute); + ExceptionAssert.sqlDataException("Missing value for parameter", statement::execute); } } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryBatchedImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryBatchedImplTest.java index 9f4d86e..924a6d4 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryBatchedImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryBatchedImplTest.java @@ -119,7 +119,7 @@ private PreparedStatement prepareScanSelect(String column) throws SQLException { @Test public void testInvalidStruct() throws SQLException { - ExceptionAssert.ydbNonRetryable("Duplicated member: key", () -> { + ExceptionAssert.ydbException("Duplicated member: key", () -> { jdbc.connection().unwrap(YdbConnection.class).prepareStatement( invalidBatchUpsertSql("c_Text", "Text"), YdbPrepareMode.DATA_QUERY_BATCH); @@ -283,7 +283,7 @@ public void executeQueryBatchWithScanRead() throws SQLException { jdbc.connection().commit(); - ExceptionAssert.ydbResultTruncated("Result #0 was truncated to 1000 rows", () -> { + ExceptionAssert.sqlException("Result #0 was truncated to 1000 rows", () -> { // Result is truncated (and we catch that) try (PreparedStatement select = prepareSimpleSelect("c_Text")) { select.executeQuery(); diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryImplTest.java index 17d6651..4d1e459 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbPreparedStatementWithDataQueryImplTest.java @@ -119,7 +119,7 @@ public void executeWrongParameters() throws SQLException { String sql = upsertSql("c_Text", "Text"); // Must be Text? try (YdbPreparedStatement statement = jdbc.connection().unwrap(YdbConnection.class).prepareStatement(sql)) { statement.setInt("key", 1); - ExceptionAssert.ydbNonRetryable("Missing value for parameter", statement::execute); + ExceptionAssert.sqlDataException("Missing value for parameter", statement::execute); } try (YdbPreparedStatement statement = jdbc.connection().unwrap(YdbConnection.class).prepareStatement(sql)) { @@ -290,7 +290,7 @@ public void executeScanQueryAsUpdate() throws SQLException { statement.setInt("key", 1); statement.setString("c_Text", "value-1"); - ExceptionAssert.ydbNonRetryable("Scan query should have a single result set", statement::execute); + ExceptionAssert.ydbException("Scan query should have a single result set", statement::execute); } } } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbStatementImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbStatementImplTest.java index fa5f231..060cd12 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbStatementImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbStatementImplTest.java @@ -270,7 +270,7 @@ public void executeSchemeQueryExplicitly() throws SQLException { statement.execute("create table scheme_query_test(id Int32, primary key(id))"); String dropSql = "scan drop table scheme_query_test"; - ExceptionAssert.ydbNonRetryable("Operation is not supported in current execution mode, check query type. ", + ExceptionAssert.ydbException("Operation is not supported in current execution mode, check query type. ", () -> statement.unwrap(YdbStatement.class).executeQuery(dropSql)); statement.unwrap(YdbStatement.class).executeSchemeQuery(dropSql); } @@ -312,7 +312,7 @@ public void executeScanQueryOnSystemTable() throws SQLException { @Test public void executeScanQueryMultiResult() { - ExceptionAssert.ydbNonRetryable("Scan query should have a single result set", + ExceptionAssert.ydbException("Scan query should have a single result set", () -> statement.executeUpdate("scan select 2 + 2;scan select 2 + 3") ); } @@ -320,7 +320,7 @@ public void executeScanQueryMultiResult() { @Test public void executeScanQueryAsUpdate() { // Looks weird - ExceptionAssert.ydbNonRetryable("Scan query should have a single result set", + ExceptionAssert.ydbException("Scan query should have a single result set", () -> statement.executeUpdate("SCAN\n" + TEST_UPSERT1_SQL) ); } diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/helper/ExceptionAssert.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/helper/ExceptionAssert.java index 0e59076..8911729 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/helper/ExceptionAssert.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/helper/ExceptionAssert.java @@ -1,16 +1,14 @@ package tech.ydb.jdbc.impl.helper; +import java.sql.SQLDataException; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLRecoverableException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.function.Executable; -import tech.ydb.jdbc.exception.YdbConditionallyRetryableException; -import tech.ydb.jdbc.exception.YdbConfigurationException; -import tech.ydb.jdbc.exception.YdbExecutionException; -import tech.ydb.jdbc.exception.YdbNonRetryableException; -import tech.ydb.jdbc.exception.YdbResultTruncatedException; +import tech.ydb.jdbc.exception.YdbSQLException; /** * @@ -19,42 +17,28 @@ public class ExceptionAssert { private ExceptionAssert() { } - public static void ydbConfiguration(String message, Executable exec) { - YdbConfigurationException ex = Assertions.assertThrows(YdbConfigurationException.class, exec, - "Invalid statement must throw YdbConfigurationException" - ); - Assertions.assertEquals(message, ex.getMessage()); - } - - public static void ydbNonRetryable(String message, Executable exec) { - YdbNonRetryableException ex = Assertions.assertThrows(YdbNonRetryableException.class, exec, - "Invalid statement must throw YdbNonRetryableException" + public static void ydbException(String message, Executable exec) { + YdbSQLException ex = Assertions.assertThrows(YdbSQLException.class, exec, + "Invalid statement must throw YdbSQLException" ); Assertions.assertTrue(ex.getMessage().contains(message), "YdbNonRetryableException '" + ex.getMessage() + "' doesn't contain message '" + message + "'"); } - public static void ydbExecution(String message, Executable exec) { - YdbExecutionException ex = Assertions.assertThrows(YdbExecutionException.class, exec, - "Invalid statement must throw YdbExecutionException" - ); - Assertions.assertEquals(message, ex.getMessage()); - } - - public static void ydbResultTruncated(String message, Executable exec) { - YdbResultTruncatedException ex = Assertions.assertThrows(YdbResultTruncatedException.class, exec, - "Invalid statement must throw YdbExecutionException" + public static void sqlDataException(String message, Executable exec) { + SQLDataException ex = Assertions.assertThrows(SQLDataException.class, exec, + "Invalid statement must throw SQLDataException" ); - Assertions.assertEquals(message, ex.getMessage()); + Assertions.assertTrue(ex.getMessage().contains(message), + "SQLDataException '" + ex.getMessage() + "' doesn't contain message '" + message + "'"); } - public static void ydbConditionallyRetryable(String message, Executable exec) { - YdbConditionallyRetryableException ex = Assertions.assertThrows(YdbConditionallyRetryableException.class, exec, - "Invalid statement must throw YdbConditionallyRetryableException" + public static void sqlRecoverable(String message, Executable exec) { + SQLRecoverableException ex = Assertions.assertThrows(SQLRecoverableException.class, exec, + "Invalid statement must throw SQLRecoverableException" ); Assertions.assertTrue(ex.getMessage().contains(message), - "YdbConditionallyRetryableException '" + ex.getMessage() - + "' doesn't contain message '" + message + "'"); + "SQLRecoverableException '" + ex.getMessage() + "' doesn't contain message '" + message + "'"); } public static void sqlFeatureNotSupported(String message, Executable exec) { From 80c07ffcc94d078c28e7a8c537e6a35e8332322a Mon Sep 17 00:00:00 2001 From: Alexandr Gorshenin Date: Fri, 1 Dec 2023 09:44:53 +0000 Subject: [PATCH 4/4] Extend exception message --- .../main/java/tech/ydb/jdbc/context/YdbExecutor.java | 11 ++++++----- .../tech/ydb/jdbc/exception/ExceptionFactory.java | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java index fd4e454..3d27988 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java @@ -80,14 +80,14 @@ public void execute(String msg, Supplier> runnableSupp public T call(String msg, Supplier>> callSupplier) throws SQLException { if (!isDebug) { - return simpleCall(callSupplier); + return simpleCall(msg, callSupplier); } logger.finest(msg); Stopwatch sw = Stopwatch.createStarted(); try { - T value = simpleCall(callSupplier); + T value = simpleCall(msg, callSupplier); logger.log(Level.FINEST, "[{0}] OK ", sw.stop()); return value; } catch (SQLException | RuntimeException ex) { @@ -96,13 +96,13 @@ public T call(String msg, Supplier>> callSupplie } } - private T simpleCall(Supplier>> supplier) throws SQLException { + private T simpleCall(String msg, Supplier>> supplier) throws SQLException { try { Result result = supplier.get().join(); issues.addAll(Arrays.asList(result.getStatus().getIssues())); return result.getValue(); } catch (UnexpectedResultException ex) { - throw ExceptionFactory.createException(ex); + throw ExceptionFactory.createException("Cannot call '" + msg + "' with " + ex.getStatus(), ex); } } @@ -110,7 +110,8 @@ private void simpleExecute(String msg, Supplier> suppl Status status = supplier.get().join(); issues.addAll(Arrays.asList(status.getIssues())); if (!status.isSuccess()) { - throw ExceptionFactory.createException(new UnexpectedResultException(msg, status)); + throw ExceptionFactory.createException("Cannot execute '" + msg + "' with " + status, + new UnexpectedResultException("Unexpected status", status)); } } } diff --git a/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java b/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java index 57a19e2..0d1ed73 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java @@ -19,18 +19,18 @@ static int getVendorCode(StatusCode code) { return code.getCode(); } - public static SQLException createException(UnexpectedResultException cause) { + public static SQLException createException(String message, UnexpectedResultException cause) { StatusCode code = cause.getStatus().getCode(); String sqlState = getSQLState(code); int vendorCode = getVendorCode(code); if (code.isRetryable(false)) { - return new YdbRetryableException(cause.getMessage(), sqlState, vendorCode, cause); + return new YdbRetryableException(message, sqlState, vendorCode, cause); } if (code.isRetryable(true)) { - return new YdbConditionallyRetryableException(cause.getMessage(), sqlState, vendorCode, cause); + return new YdbConditionallyRetryableException(message, sqlState, vendorCode, cause); } - return new YdbSQLException(cause.getMessage(), sqlState, vendorCode, cause); + return new YdbSQLException(message, sqlState, vendorCode, cause); } }