Skip to content

Commit

Permalink
Merge pull request #35 from alex268/release_v2.0.4
Browse files Browse the repository at this point in the history
Use standart exception classes for detecting retryable problems
  • Loading branch information
alex268 committed Dec 1, 2023
2 parents c7a2ea6 + 80c07ff commit 12063ff
Show file tree
Hide file tree
Showing 34 changed files with 187 additions and 240 deletions.
5 changes: 2 additions & 3 deletions jdbc/src/main/java/tech/ydb/jdbc/common/MappingSetters.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
};
}
Expand All @@ -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);
}
};
}
Expand Down
5 changes: 2 additions & 3 deletions jdbc/src/main/java/tech/ydb/jdbc/context/YdbContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

Expand Down
35 changes: 14 additions & 21 deletions jdbc/src/main/java/tech/ydb/jdbc/context/YdbExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -62,15 +62,15 @@ public Session createSession(YdbContext ctx) throws SQLException {

public void execute(String msg, Supplier<CompletableFuture<Status>> runnableSupplier) throws SQLException {
if (!isDebug) {
simpleExecute(runnableSupplier);
simpleExecute(msg, runnableSupplier);
return;
}

logger.finest(msg);
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() });
Expand All @@ -80,14 +80,14 @@ public void execute(String msg, Supplier<CompletableFuture<Status>> runnableSupp

public <T> T call(String msg, Supplier<CompletableFuture<Result<T>>> 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) {
Expand All @@ -96,29 +96,22 @@ public <T> T call(String msg, Supplier<CompletableFuture<Result<T>>> callSupplie
}
}

private <T> T simpleCall(Supplier<CompletableFuture<Result<T>>> supplier) throws SQLException {
private <T> T simpleCall(String msg, Supplier<CompletableFuture<Result<T>>> supplier) throws SQLException {
try {
Result<T> 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("Cannot call '" + msg + "' with " + ex.getStatus(), ex);
}
}

private void simpleExecute(Supplier<CompletableFuture<Status>> 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<CompletableFuture<Status>> 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("Cannot execute '" + msg + "' with " + status,
new UnexpectedResultException("Unexpected status", status));
}
}
}
36 changes: 36 additions & 0 deletions jdbc/src/main/java/tech/ydb/jdbc/exception/ExceptionFactory.java
Original file line number Diff line number Diff line change
@@ -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(String message, UnexpectedResultException cause) {
StatusCode code = cause.getStatus().getCode();
String sqlState = getSQLState(code);
int vendorCode = getVendorCode(code);

if (code.isRetryable(false)) {
return new YdbRetryableException(message, sqlState, vendorCode, cause);
}
if (code.isRetryable(true)) {
return new YdbConditionallyRetryableException(message, sqlState, vendorCode, cause);
}

return new YdbSQLException(message, sqlState, vendorCode, cause);
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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;
}
}

This file was deleted.

21 changes: 21 additions & 0 deletions jdbc/src/main/java/tech/ydb/jdbc/exception/YdbSQLException.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
40 changes: 0 additions & 40 deletions jdbc/src/main/java/tech/ydb/jdbc/exception/YdbStatusException.java

This file was deleted.

3 changes: 1 addition & 2 deletions jdbc/src/main/java/tech/ydb/jdbc/impl/BaseYdbStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
}
Expand Down
6 changes: 2 additions & 4 deletions jdbc/src/main/java/tech/ydb/jdbc/impl/YdbConnectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

}
}
Expand Down Expand Up @@ -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);
}
}

Expand Down

0 comments on commit 12063ff

Please sign in to comment.