Skip to content

Commit 45b572f

Browse files
fix(bqjdbc): Log exception messages - part 3 (#12920)
b/505826451 **1. Centralization of Exception Logging** Moved the responsibility of logging exceptions from the throw sites to the constructors of the custom exception classes themselves. This ensures all instances are logged automatically and consistently. Added loggers and logging calls to constructors of the following custom exception classes: - BigQueryJdbcRuntimeException - BigQueryJdbcException - BigQueryConversionException - BigQueryJdbcCoercionException - BigQueryJdbcCoercionNotFoundException - BigQueryJdbcSqlFeatureNotSupportedException - BigQueryJdbcSqlSyntaxErrorException **2. Updates to BigQueryJdbcCustomLogger** To support the above changes, the custom logger was updated: - Modified caller inference to skip classes in the com.google.cloud.bigquery.exception package. This ensures that the logs point to the method that threw the exception rather than the exception constructor itself. - Made the class, its constructor, and severe methods public so they can be accessed by exception classes residing in a different package. **3. Cleanup of Redundant Logging** After centralizing the logging, removed manual LOG.severe calls that were followed by a throw of the updated custom exceptions in functional classes. Files cleaned up: - BigQueryConnection.java - BigQueryStatement.java - BigQueryPreparedStatement.java - BigQueryJdbcOAuthUtility.java - BigQueryArrowResultSet.java - BigQueryJsonResultSet.java - BigQueryBaseResultSet.java - BigQueryTypeCoercer.java - BigQueryJdbcTypeMappings.java - PooledConnectionDataSource.java **4. Addition of Logging for Standard Exceptions** For standard Java exceptions (like IllegalArgumentException and IllegalStateException) that do not log themselves, added manual severe logging before they are thrown to ensure they are not missed in the logs. Files updated: - BigQueryConnection.java - BigQueryCallableStatement.java - BigQueryStatement.java. **5. Logger Signature Refactor** Updated BigQueryJdbcCustomLogger.java to take Throwable as the second parameter in severe methods, and updated calls across 17 files to match this signature. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent eb412a1 commit 45b572f

33 files changed

Lines changed: 352 additions & 258 deletions

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryConversionException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@
1616

1717
package com.google.cloud.bigquery.exception;
1818

19+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
1920
import java.sql.SQLException;
2021

2122
/**
2223
* Exception for errors that occur when the driver cannot convert a value from one type to another.
2324
*/
2425
public class BigQueryConversionException extends SQLException {
26+
private static final BigQueryJdbcCustomLogger LOG =
27+
new BigQueryJdbcCustomLogger(BigQueryConversionException.class.getName());
2528

2629
public BigQueryConversionException(String message, Throwable cause) {
2730
super(message, cause);
31+
LOG.severe(message, this);
2832
}
2933
}

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryJdbcCoercionException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package com.google.cloud.bigquery.exception;
1818

1919
import com.google.api.core.InternalApi;
20+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
2021

2122
/**
2223
* Thrown to indicate that the coercion was attempted but couldn't be performed successfully because
2324
* of some error.
2425
*/
2526
@InternalApi
2627
public class BigQueryJdbcCoercionException extends RuntimeException {
28+
private static final BigQueryJdbcCustomLogger LOG =
29+
new BigQueryJdbcCustomLogger(BigQueryJdbcCoercionException.class.getName());
2730

2831
/**
2932
* Construct a new exception with the specified cause.
@@ -32,5 +35,6 @@ public class BigQueryJdbcCoercionException extends RuntimeException {
3235
*/
3336
public BigQueryJdbcCoercionException(Exception cause) {
3437
super("Coercion error", cause);
38+
LOG.severe("Coercion error", this);
3539
}
3640
}

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryJdbcCoercionNotFoundException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package com.google.cloud.bigquery.exception;
1818

1919
import com.google.api.core.InternalApi;
20+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
2021

2122
/**
2223
* Thrown to indicate that the current TypeCoercer can not perform the coercion as the Coercion
2324
* implementation is not registered for the mentioned source and target type.
2425
*/
2526
@InternalApi
2627
public class BigQueryJdbcCoercionNotFoundException extends RuntimeException {
28+
private static final BigQueryJdbcCustomLogger LOG =
29+
new BigQueryJdbcCustomLogger(BigQueryJdbcCoercionNotFoundException.class.getName());
2730

2831
/**
2932
* Construct a new exception.
@@ -36,5 +39,6 @@ public BigQueryJdbcCoercionNotFoundException(Class<?> source, Class<?> target) {
3639
String.format(
3740
"Coercion not found for [%s -> %s] conversion",
3841
source.getCanonicalName(), target.getCanonicalName()));
42+
LOG.severe(this.getMessage(), this);
3943
}
4044
}

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryJdbcException.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
package com.google.cloud.bigquery.exception;
1818

1919
import com.google.cloud.bigquery.BigQueryException;
20+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
2021
import java.sql.SQLException;
2122

2223
public class BigQueryJdbcException extends SQLException {
24+
private static final BigQueryJdbcCustomLogger LOG =
25+
new BigQueryJdbcCustomLogger(BigQueryJdbcException.class.getName());
2326
private BigQueryException bigQueryException = null;
2427

2528
/**
@@ -29,6 +32,7 @@ public class BigQueryJdbcException extends SQLException {
2932
*/
3033
public BigQueryJdbcException(String message) {
3134
super(message);
35+
LOG.severe(message, this);
3236
}
3337

3438
/**
@@ -38,16 +42,19 @@ public BigQueryJdbcException(String message) {
3842
*/
3943
public BigQueryJdbcException(InterruptedException ex) {
4044
super(ex);
45+
LOG.severe(ex.getMessage(), this);
4146
}
4247

4348
/**
4449
* Constructs a new BigQueryJdbcException from BigQueryException
4550
*
51+
* @param message Specific message that is being added to the Exception.
4652
* @param ex The BigQueryException to be thrown.
4753
*/
48-
public BigQueryJdbcException(BigQueryException ex) {
49-
super(ex);
54+
public BigQueryJdbcException(String message, BigQueryException ex) {
55+
super(message, ex);
5056
this.bigQueryException = ex;
57+
LOG.severe(ex.getMessage(), this);
5158
}
5259

5360
/**
@@ -58,6 +65,7 @@ public BigQueryJdbcException(BigQueryException ex) {
5865
*/
5966
public BigQueryJdbcException(String message, Throwable cause) {
6067
super(message, cause);
68+
LOG.severe(message, this);
6169
}
6270

6371
/**
@@ -68,6 +76,7 @@ public BigQueryJdbcException(String message, Throwable cause) {
6876
*/
6977
public BigQueryJdbcException(Throwable cause) {
7078
super(cause);
79+
LOG.severe(cause.getMessage(), this);
7180
}
7281

7382
public BigQueryException getBigQueryException() {

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryJdbcRuntimeException.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@
1616

1717
package com.google.cloud.bigquery.exception;
1818

19+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
20+
1921
public class BigQueryJdbcRuntimeException extends RuntimeException {
2022

23+
private static final BigQueryJdbcCustomLogger LOG =
24+
new BigQueryJdbcCustomLogger(BigQueryJdbcRuntimeException.class.getName());
25+
2126
/**
2227
* Constructs a new BigQueryJdbcRuntimeException with the given message.
2328
*
2429
* @param message The detail message.
2530
*/
2631
public BigQueryJdbcRuntimeException(String message) {
2732
super(message);
33+
LOG.severe(message, this);
2834
}
2935

3036
/**
@@ -34,6 +40,7 @@ public BigQueryJdbcRuntimeException(String message) {
3440
*/
3541
public BigQueryJdbcRuntimeException(Throwable ex) {
3642
super(ex);
43+
LOG.severe(ex.getMessage(), this);
3744
}
3845

3946
/**
@@ -44,5 +51,11 @@ public BigQueryJdbcRuntimeException(Throwable ex) {
4451
*/
4552
public BigQueryJdbcRuntimeException(String message, InterruptedException ex) {
4653
super(message, ex);
54+
LOG.severe(message, this);
55+
}
56+
57+
public BigQueryJdbcRuntimeException(String message, Throwable ex) {
58+
super(message, ex);
59+
LOG.severe(message, this);
4760
}
4861
}

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryJdbcSqlFeatureNotSupportedException.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,21 @@
1717
package com.google.cloud.bigquery.exception;
1818

1919
import com.google.cloud.bigquery.BigQueryException;
20+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
2021
import java.sql.SQLFeatureNotSupportedException;
2122

2223
public class BigQueryJdbcSqlFeatureNotSupportedException extends SQLFeatureNotSupportedException {
24+
private static final BigQueryJdbcCustomLogger LOG =
25+
new BigQueryJdbcCustomLogger(BigQueryJdbcSqlFeatureNotSupportedException.class.getName());
26+
2327
/**
2428
* Constructs a new BigQueryJdbcSqlFeatureNotSupportedException with the given message.
2529
*
2630
* @param message The detail message.
2731
*/
2832
public BigQueryJdbcSqlFeatureNotSupportedException(String message) {
2933
super(message);
34+
LOG.severe(message, this);
3035
}
3136

3237
/**
@@ -36,5 +41,6 @@ public BigQueryJdbcSqlFeatureNotSupportedException(String message) {
3641
*/
3742
public BigQueryJdbcSqlFeatureNotSupportedException(BigQueryException ex) {
3843
super(ex);
44+
LOG.severe(ex.getMessage(), this);
3945
}
4046
}

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/exception/BigQueryJdbcSqlSyntaxErrorException.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud.bigquery.exception;
1818

1919
import com.google.cloud.bigquery.BigQueryException;
20+
import com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger;
2021
import java.sql.SQLSyntaxErrorException;
2122

2223
/**
@@ -25,12 +26,21 @@
2526
* rules.
2627
*/
2728
public class BigQueryJdbcSqlSyntaxErrorException extends SQLSyntaxErrorException {
29+
private static final BigQueryJdbcCustomLogger LOG =
30+
new BigQueryJdbcCustomLogger(BigQueryJdbcSqlSyntaxErrorException.class.getName());
31+
2832
/**
2933
* Constructs a new BigQueryJdbcSqlSyntaxErrorException from BigQueryException
3034
*
3135
* @param ex The BigQueryException to be thrown.
3236
*/
3337
public BigQueryJdbcSqlSyntaxErrorException(BigQueryException ex) {
3438
super(ex.getMessage(), "Incorrect SQL syntax.");
39+
LOG.severe(ex.getMessage(), this);
40+
}
41+
42+
public BigQueryJdbcSqlSyntaxErrorException(String message, BigQueryException ex) {
43+
super(message, ex);
44+
LOG.severe(message, this);
3545
}
3646
}

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryArrowResultSet.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private BigQueryArrowResultSet(
108108
try {
109109
this.arrowDeserializer = new ArrowDeserializer(arrowSchema);
110110
} catch (IOException ex) {
111-
throw new BigQueryJdbcException(ex);
111+
throw new BigQueryJdbcException("IOException during ArrowDeserializer creation", ex);
112112
}
113113
}
114114
}
@@ -215,8 +215,11 @@ public boolean next() throws SQLException {
215215
checkClosed();
216216
if (this.isNested) {
217217
if (this.currentNestedBatch == null || this.currentNestedBatch.getNestedRecords() == null) {
218-
throw new IllegalStateException(
219-
"currentNestedBatch/JsonStringArrayList can not be null working with the nested record");
218+
IllegalStateException ex =
219+
new IllegalStateException(
220+
"currentNestedBatch/JsonStringArrayList can not be null working with the nested record");
221+
LOG.severe(ex.getMessage(), ex);
222+
throw ex;
220223
}
221224
if (this.nestedRowIndex < (this.toIndexExclusive - 1)) {
222225
/* Check if there's a next record in the array which can be read */
@@ -283,12 +286,16 @@ private Object getObjectInternal(int columnIndex) throws SQLException {
283286
// BigQuery doesn't support multidimensional arrays, so
284287
// just the default row num column (1) and the actual column (2) is supposed to be read
285288
if (!(columnIndex == 1 || columnIndex == 2)) {
286-
287-
throw new IllegalArgumentException(
288-
"Column index is required to be 1 or 2 for nested arrays");
289+
IllegalArgumentException ex =
290+
new IllegalArgumentException("Column index is required to be 1 or 2 for nested arrays");
291+
LOG.severe(ex.getMessage(), ex);
292+
throw ex;
289293
}
290294
if (this.currentNestedBatch.getNestedRecords() == null) {
291-
throw new IllegalStateException("JsonStringArrayList cannot be null for nested records.");
295+
IllegalStateException ex =
296+
new IllegalStateException("JsonStringArrayList cannot be null for nested records.");
297+
LOG.severe(ex.getMessage(), ex);
298+
throw ex;
292299
}
293300
// For Arrays the first column is Index, ref:
294301
// https://docs.oracle.com/javase/7/docs/api/java/sql/Array.html#getResultSet()

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryBaseArray.java

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,36 +71,24 @@ public final int getBaseType() {
7171

7272
@Override
7373
public final Object getArray(Map<String, Class<?>> map) throws SQLException {
74-
BigQueryJdbcSqlFeatureNotSupportedException ex =
75-
new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
76-
LOG.severe(ex, CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
77-
throw ex;
74+
throw new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
7875
}
7976

8077
@Override
8178
public final Object getArray(long index, int count, Map<String, Class<?>> map)
8279
throws SQLException {
83-
BigQueryJdbcSqlFeatureNotSupportedException ex =
84-
new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
85-
LOG.severe(ex, CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
86-
throw ex;
80+
throw new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
8781
}
8882

8983
@Override
9084
public final ResultSet getResultSet(Map<String, Class<?>> map) throws SQLException {
91-
BigQueryJdbcSqlFeatureNotSupportedException ex =
92-
new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
93-
LOG.severe(ex, CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
94-
throw ex;
85+
throw new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
9586
}
9687

9788
@Override
9889
public final ResultSet getResultSet(long index, int count, Map<String, Class<?>> map)
9990
throws SQLException {
100-
BigQueryJdbcSqlFeatureNotSupportedException ex =
101-
new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
102-
LOG.severe(ex, CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
103-
throw ex;
91+
throw new BigQueryJdbcSqlFeatureNotSupportedException(CUSTOMER_TYPE_MAPPING_NOT_SUPPORTED);
10492
}
10593

10694
protected Object getArrayInternal(int fromIndex, int toIndexExclusive) {
@@ -119,7 +107,7 @@ protected void ensureValid() throws IllegalStateException {
119107
LOG.finest("++enter++");
120108
if (!this.valid) {
121109
IllegalStateException ex = new IllegalStateException(INVALID_ARRAY);
122-
LOG.severe(ex, INVALID_ARRAY);
110+
LOG.severe(INVALID_ARRAY, ex);
123111
throw ex;
124112
}
125113
}
@@ -146,7 +134,7 @@ protected Tuple<Integer, Integer> createRange(long index, int count, int size)
146134
String.format(
147135
"The array index is out of range: %d, number of elements: %d.",
148136
index + count, size));
149-
LOG.severe(ex, ex.getMessage());
137+
LOG.severe(ex.getMessage(), ex);
150138
throw ex;
151139
}
152140
long toIndex = normalisedFromIndex + count;

java-bigquery/google-cloud-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryBaseResultSet.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ public void close() {
109109

110110
protected SQLException createCoercionException(
111111
int columnIndex, Class<?> targetClass, Exception cause) throws SQLException {
112-
LOG.severe(cause, "Coercion failed");
113112
checkClosed();
114113
StandardSQLTypeName type;
115114
String typeName;
@@ -127,7 +126,7 @@ protected SQLException createCoercionException(
127126
SQLException ex =
128127
new SQLException(
129128
"For a nested ResultSet from an Array, columnIndex must be 1 or 2.", cause);
130-
LOG.severe(ex, "For a nested ResultSet from an Array, columnIndex must be 1 or 2.");
129+
LOG.severe(ex.getMessage(), ex);
131130
throw ex;
132131
}
133132
} else {
@@ -149,23 +148,23 @@ private StandardSQLTypeName getStandardSQLTypeName(int columnIndex) throws SQLEx
149148
} else if (columnIndex == 2) {
150149
if (this.schema == null || this.schema.getFields().isEmpty()) {
151150
SQLException ex = new SQLException("Schema not available for nested result set.");
152-
LOG.severe(ex, "Schema not available for nested result set.");
151+
LOG.severe("Schema not available for nested result set.", ex);
153152
throw ex;
154153
}
155154
Field arrayField = this.schema.getFields().get(0);
156155
return arrayField.getType().getStandardType();
157156
} else {
158157
SQLException ex =
159158
new SQLException("For a nested ResultSet from an Array, columnIndex must be 1 or 2.");
160-
LOG.severe(ex, "For a nested ResultSet from an Array, columnIndex must be 1 or 2.");
159+
LOG.severe("For a nested ResultSet from an Array, columnIndex must be 1 or 2.", ex);
161160
throw ex;
162161
}
163162
} else {
164163
if (this.schemaFieldList == null
165164
|| columnIndex > this.schemaFieldList.size()
166165
|| columnIndex < 1) {
167166
SQLException ex = new SQLException("Invalid column index: " + columnIndex);
168-
LOG.severe(ex, "Invalid column index: " + columnIndex);
167+
LOG.severe("Invalid column index: " + columnIndex, ex);
169168
throw ex;
170169
}
171170
Field field = this.schemaFieldList.get(columnIndex - 1);
@@ -228,7 +227,9 @@ protected int getColumnIndex(String columnLabel) throws SQLException {
228227
LOG.finest("++enter++");
229228
checkClosed();
230229
if (columnLabel == null) {
231-
throw new SQLException("Column label cannot be null");
230+
SQLException ex = new SQLException("Column label cannot be null");
231+
LOG.severe(ex.getMessage(), ex);
232+
throw ex;
232233
}
233234
// use schema to get the column index, add 1 for SQL index
234235
return this.schemaFieldList.getIndex(columnLabel) + 1;

0 commit comments

Comments
 (0)