private static void handleAzureException ( Exception ex , int retryCount , String operation , SFSession connection , String command , SnowflakeAzureClient azClient ) throws SnowflakeSQLException { // no need to retry if it is invalid key exception if ( ex . getCause ( ) instanceof InvalidKeyException ) { // Most likely cause is that the unlimited strength policy files are not installed // Log the error and throw a message that explains the cause SnowflakeFileTransferAgent . throwJCEMissingError ( operation , ex ) ; } if ( ( ( StorageException ) ex ) . getHttpStatusCode ( ) == 403 ) { // A 403 indicates that the SAS token has expired, // we need to refresh the Azure client with the new token SnowflakeFileTransferAgent . renewExpiredToken ( connection , command , azClient ) ; } if ( ex instanceof StorageException ) { StorageException se = ( StorageException ) ex ; // If we have exceeded the max number of retries, propagate the error if ( retryCount > azClient . getMaxRetries ( ) ) { throw new SnowflakeSQLException ( se , SqlState . SYSTEM_ERROR , ErrorCode . AZURE_SERVICE_ERROR . getMessageCode ( ) , operation , se . getErrorCode ( ) , se . getExtendedErrorInformation ( ) , se . getHttpStatusCode ( ) , se . getMessage ( ) ) ; } else { logger . debug ( "Encountered exception ({}) during {}, retry count: {}" , ex . getMessage ( ) , operation , retryCount ) ; logger . debug ( "Stack trace: " , ex ) ; // exponential backoff up to a limit int backoffInMillis = azClient . getRetryBackoffMin ( ) ; if ( retryCount > 1 ) { backoffInMillis <<= ( Math . min ( retryCount - 1 , azClient . getRetryBackoffMaxExponent ( ) ) ) ; } try { logger . debug ( "Sleep for {} milliseconds before retry" , backoffInMillis ) ; Thread . sleep ( backoffInMillis ) ; } catch ( InterruptedException ex1 ) { // ignore } if ( se . getHttpStatusCode ( ) == 403 ) { // A 403 indicates that the SAS token has expired, // we need to refresh the Azure client with the new token SnowflakeFileTransferAgent . renewExpiredToken ( connection , command , azClient ) ; } } } else { if ( ex instanceof InterruptedException || SnowflakeUtil . getRootCause ( ex ) instanceof SocketTimeoutException ) { if ( retryCount > azClient . getMaxRetries ( ) ) { throw new SnowflakeSQLException ( ex , SqlState . SYSTEM_ERROR , ErrorCode . IO_ERROR . getMessageCode ( ) , "Encountered exception during " + operation + ": " + ex . getMessage ( ) ) ; } else { logger . debug ( "Encountered exception ({}) during {}, retry count: {}" , ex . getMessage ( ) , operation , retryCount ) ; } } else { throw new SnowflakeSQLException ( ex , SqlState . SYSTEM_ERROR , ErrorCode . IO_ERROR . getMessageCode ( ) , "Encountered exception during " + operation + ": " + ex . getMessage ( ) ) ; } } }
Handles exceptions thrown by Azure Storage It will retry transient errors as defined by the Azure Client retry policy It will re - create the client if the SAS token has expired and re - try