public static ThrowableInfo isRetryableException()

in services/library/src/main/java/com/google/cloud/pso/bq_pii_classifier/helpers/ControllerExceptionHelper.java [41:110]


    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" );
            }
        }

        // 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(""));

    }