in services/library/src/main/java/com/google/cloud/pso/bq_snapshot_manager/helpers/ControllerExceptionHelper.java [47:137]
public static ThrowableInfo isRetryableException(Throwable throwable) {
Class exceptionClass = throwable.getClass();
// 1. Check if it's any type of rate limit exception. If so, retry.
// Thrown by DLP
if (StatusRuntimeException.class.isAssignableFrom(exceptionClass)) {
StatusRuntimeException statusRuntimeException = (StatusRuntimeException) throwable;
if (statusRuntimeException.getStatus() != null && statusRuntimeException.getStatus().equals(Status.RESOURCE_EXHAUSTED)) {
return new ThrowableInfo(throwable, true, "Retryable: 'status' = RESOURCE_EXHAUSTED assignable from StatusRuntimeException");
}
}
// Thrown by BigQuery
if (BigQueryException.class.isAssignableFrom(exceptionClass)) {
BigQueryException bigQueryException = (BigQueryException) throwable;
// when hitting the concurrent interactive queries
// bigQueryException.getReason() is sometimes null.
if (bigQueryException.getReason() != null && bigQueryException.getReason().equals("jobRateLimitExceeded")) {
return new ThrowableInfo(throwable,
true,
"Retryable: 'reason' = jobRateLimitExceeded assignable from BigQueryException");
}
// handling "Exceeded rate limits: too many api requests per user per method for this user_method"
if (bigQueryException.getReason() != null && bigQueryException.getReason().equals("rateLimitExceeded")) {
return new ThrowableInfo(throwable,
true,
"Retryable: 'reason' = rateLimitExceeded assignable from BigQueryException");
}
// handling transit internalError https://cloud.google.com/bigquery/docs/error-messages#errortable
if (bigQueryException.getCode() == 500 || bigQueryException.getCode() == 503) {
return new ThrowableInfo(throwable,
true,
String.format("Retryable: 'code' = %s assignable from BigQueryException",
bigQueryException.getCode()));
}
// handling transit internalError https://cloud.google.com/bigquery/docs/error-messages#errortable
if (bigQueryException.getReason() != null && bigQueryException.getReason().equals("internalError")
) {
return new ThrowableInfo(throwable,
true,
String.format("Retryable: 'reason' = %s assignable from BigQueryException",
bigQueryException.getReason()));
}
}
// BaseServiceException Thrown by BigQuery
if (BaseServiceException.class.isAssignableFrom(exceptionClass)) {
BaseServiceException baseServiceException = (BaseServiceException) throwable;
if (baseServiceException.getCode() == 429) {
return new ThrowableInfo(throwable, true, "Retryable: 'code' = 429 assignable from BaseServiceException");
}
}
// 2. check if the exception inherits (at any level) from any Retryable Exception that we explicitly define
for (Class retryableExClass : RETRYABLE_EXCEPTIONS) {
if (retryableExClass.isAssignableFrom(exceptionClass)) {
return new ThrowableInfo(throwable, true, String.format("Retryable: isAssignableFrom %s ", retryableExClass.getName()));
}
}
// 3. check if the exception is caused by a Retryable Exception
for (Class retryableExClass : RETRYABLE_EXCEPTIONS) {
if (retryableExClass.isAssignableFrom(exceptionClass)) {
return new ThrowableInfo(throwable, true, String.format("Retryable: isAssignableFrom %s ", retryableExClass.getName()));
}
}
// 4. Check if it's any type of isRetryable. If so, retry.
// Thrown by BigQuery:
// Base class for all gcp service exceptions.
// Check if it's a retryable BaseServiceException
if (BaseServiceException.class.isAssignableFrom(exceptionClass)) {
BaseServiceException baseServiceException = (BaseServiceException) throwable;
return new ThrowableInfo(throwable, baseServiceException.isRetryable(), String.format("Check: isAssignableFrom BaseServiceException"));
}
// Check if it's Retryable ApiException
if (ApiException.class.isAssignableFrom(exceptionClass)) {
ApiException apiEx = (ApiException) throwable;
return new ThrowableInfo(throwable, apiEx.isRetryable(), String.format("Check: isAssignableFrom BaseServiceException"));
}
// if not, log and ACK so that it's not retried
return new ThrowableInfo(throwable, false, String.format(""));
}